首页 文章 精选 留言 我的

精选列表

搜索[自动装配],共10000篇文章
优秀的个人博客,低调大师

运维编排场景系列-----给ECS实例自动打TAG

Tag简介和场景 对于一般的资源管理需求,都是针对一个用户下数量较多的情况,当实例等数量较多时,对实例进行运维管理等操作就会变得比较困难,有时候甚至需要采取拆分账号的方式管理不同部门或者不同用途的资源。如果采用Tag进行资源的分类管理,会大大简化这个问题。 首先,我们可以针对实例的使用场景进行分类,在一般的开发场景中,机器一般有多个分类:开发测试环境、打包环境、生产环境等。这些机器的运维管理是绝对隔绝的,因此要在Tag上对其进行区分,在开发测试机器上,可以增加标签(增加方式详见下一节)key为env、value为test;在生产机器上,可以增加标签key为env、value为product。形成如下图的机器分类。 ​ ​ 我们可以使用不同的维度来给机器

优秀的个人博客,低调大师

Spring Cloud Stream消费失败后的处理策略(一):自动重试

之前写了几篇关于Spring Cloud Stream使用中的常见问题,比如: 如何处理消息重复消费 如何消费自己生产的消息 下面几天就集中来详细聊聊,当消息消费失败之后该如何处理的几种方式。不过不论哪种方式,都需要与具体业务结合,解决不同业务场景可能出现的问题。 今天第一节,介绍一下Spring Cloud Stream中默认就已经配置了的一个异常解决方案:重试! 应用场景 依然要明确一点,任何解决方案都要结合具体的业务实现来确定,不要有了锤子看什么问题都是钉子。那么重试可以解决什么问题呢?由于重试的基础逻辑并不会改变,所以通常重试只能解决因环境不稳定等外在因素导致的失败情况,比如:当我们接收到某个消息之后,需要调用一个外部的Web Service做一些事情,这个时候如果与外部系统的网络出现了抖动,导致调用失败而抛出异常。这个时候,通过重试消息消费的具体逻辑,可能在下一次调用的时候,就能完成整合业务动作,从而解决刚才所述的问题。 动手试试 先通过一个小例子来看看Spring Cloud Stream默认的重试机制是如何运作的。之前在如何消费自己生产的消息一文中的例子,我们可以继续沿用,或者也可以精简一些,都写到一个主类中,比如下面这样: @EnableBinding(TestApplication.TestTopic.class) @SpringBootApplication public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } @RestController static class TestController { @Autowired private TestTopic testTopic; /** * 消息生产接口 * @param message * @return */ @GetMapping("/sendMessage") public String messageWithMQ(@RequestParam String message) { testTopic.output().send(MessageBuilder.withPayload(message).build()); return "ok"; } } /** * 消息消费逻辑 */ @Slf4j @Component static class TestListener { @StreamListener(TestTopic.INPUT) public void receive(String payload) { log.info("Received: " + payload); throw new RuntimeException("Message consumer failed!"); } } interface TestTopic { String OUTPUT = "example-topic-output"; String INPUT = "example-topic-input"; @Output(OUTPUT) MessageChannel output(); @Input(INPUT) SubscribableChannel input(); } } 内容很简单,既包含了消息的生产,也包含了消息消费。与之前例子不同的就是在消息消费逻辑中,主动的抛出了一个异常来模拟消息的消费失败。 在启动应用之前,还要记得配置一下输入输出通道对应的物理目标(exchange或topic名),比如: spring.cloud.stream.bindings.example-topic-input.destination=test-topic spring.cloud.stream.bindings.example-topic-output.destination=test-topic 完成了上面配置之后,就可以启动应用,并尝试访问localhost:8080/sendMessage?message=hello接口来发送一个消息到MQ中了。此时可以看到类似下面的日志: 2018-12-10 11:20:21.345 INFO 30499 --- [w2p2yKethOsqg-1] c.d.stream.TestApplication$TestListener : Received: hello 2018-12-10 11:20:22.350 INFO 30499 --- [w2p2yKethOsqg-1] c.d.stream.TestApplication$TestListener : Received: hello 2018-12-10 11:20:24.354 INFO 30499 --- [w2p2yKethOsqg-1] c.d.stream.TestApplication$TestListener : Received: hello 2018-12-10 11:20:54.651 ERROR 30499 --- [w2p2yKethOsqg-1] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessagingException: Exception thrown while invoking com.didispace.stream.TestApplication$TestListener#receive[1 args]; nested exception is java.lang.RuntimeException: Message consumer failed!, failedMessage=GenericMessage [payload=byte[5], headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedRoutingKey=test-topic, amqp_receivedExchange=test-topic, amqp_deliveryTag=2, deliveryAttempt=3, amqp_consumerQueue=test-topic.anonymous.EuqBJu66Qw2p2yKethOsqg, amqp_redelivered=false, id=a89adf96-7de2-f29d-20b6-2fcb0c64cd8c, amqp_consumerTag=amq.ctag-XFy6vXU2w4RB_NRBzImWTA, contentType=application/json, timestamp=1544412051638}] at org.springframework.cloud.stream.binding.StreamListenerMessageHandler.handleRequestMessage(StreamListenerMessageHandler.java:63) at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109) at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:158) at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132) at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105) at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73) at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:445) at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:394) at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:181) at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:160) at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47) at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108) at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:203) at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter.access$1100(AmqpInboundChannelAdapter.java:60) at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.lambda$onMessage$0(AmqpInboundChannelAdapter.java:214) at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:287) at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:180) at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.onMessage(AmqpInboundChannelAdapter.java:211) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1414) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1337) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1324) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1303) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:817) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:801) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:77) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1042) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.RuntimeException: Message consumer failed! at com.didispace.stream.TestApplication$TestListener.receive(TestApplication.java:65) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:181) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:114) at org.springframework.cloud.stream.binding.StreamListenerMessageHandler.handleRequestMessage(StreamListenerMessageHandler.java:55) ... 27 more 从日志中可以看到,一共输出了三次Received: hello,也就是说消息消费逻辑执行了3次,然后抛出了最终执行失败的异常。 设置重复次数 默认情况下Spring Cloud Stream会重试3次,我们也可以通过配置的方式修改这个默认配置,比如下面的配置可以将重试次数调整为1次: spring.cloud.stream.bindings.example-topic-input.consumer.max-attempts=1 对于一些纯内部计算逻辑,不需要依赖外部环境,如果出错通常是代码逻辑错误的情况下,不论我们如何重试都会继续错误的业务逻辑可以将该参数设置为0,避免不必要的重试影响消息处理的速度。 深入思考 完成了上面的基础尝试之后,再思考下面两个问题: 问题一:如果在重试过程中消息处理成功了,还会有异常信息吗? 答案是不会。因为重试过程是消息处理的一个整体,如果某一次重试成功了,会任务对所收到消息的消费成功了。 这个问题可以在上述例子中做一些小改动来验证,比如: @Slf4j @Component static class TestListener { int counter = 1; @StreamListener(TestTopic.INPUT) public void receive(String payload) { log.info("Received: " + payload + ", " + counter); if (counter == 3) { counter = 1; return; } else { counter++; throw new RuntimeException("Message consumer failed!"); } } } 通过加入一个计数器,当重试是第3次的时候,不抛出异常来模拟消费逻辑处理成功了。此时重新运行程序,并调用接口localhost:8080/sendMessage?message=hello,可以获得如下日志结果,并没有异常打印出来。 2018-12-10 16:07:38.390 INFO 66468 --- [L6MGAj-MAj7QA-1] c.d.stream.TestApplication$TestListener : Received: hello, 1 2018-12-10 16:07:39.398 INFO 66468 --- [L6MGAj-MAj7QA-1] c.d.stream.TestApplication$TestListener : Received: hello, 2 2018-12-10 16:07:41.402 INFO 66468 --- [L6MGAj-MAj7QA-1] c.d.stream.TestApplication$TestListener : Received: hello, 3 也就是,虽然前两次消费抛出了异常,但是并不影响最终的结果,也不会打印中间过程的异常,避免了对日志告警产生误报等问题。 问题二:如果重试都失败之后应该怎么办呢? 如果消息在重试了还是失败之后,目前的配置唯一能做的就是将异常信息记录下来,进行告警。由于日志中有消息的消息信息描述,所以应用维护者可以根据这些信息来做一些补救措施。 当然,这样的做法显然不是最好的,因为太过麻烦。那么怎么做才好呢?且听下回分解! 代码示例 本文示例读者可以通过查看下面仓库的中的stream-exception-handler-1项目: Github Gitee 如果您对这些感兴趣,欢迎star、follow、收藏、转发给予支持! 以下专题教程也许您会有兴趣 Spring Boot基础教程 Spring Cloud基础教程

优秀的个人博客,低调大师

python linux 系统管理与自动化运维

pypdf2 图片:pillow 邮件:smtplib yagmail:简单发送邮件 image.png image.png 接收邮件:imapclient image.png settools打包 python-nmap image.png image.png ipy。。。。。。 dnspython... 同时处理多台服务器:polysh wget http://guichaz.free.fr/polysh/files/polysh-0.4.tar.gz tar -zxvf polysh-0.4.tar.gz cd polysh-0.4 python setup.py install 获取用户输入:pexcept paramiko:https://blog.csdn.net/l1028386804/article/details/79029041 脚本操作ssh fabric from fabric.api import * #导入fabric.api模块 env.hosts= ['192.168.122.101','192.168.122.102','192.168.122.103'] #指定远端服务器的ip地址。如果有dns解析的也可以写主机名。 env.password='indionce' #指定远端主机的密码,如果各个密码不相同可以使用一个字典指定,例如:env.password={“root@192.168.122.101”:"indionce"} @runs_once def local_uname(): #定义一个本地任务的函数 local('uname -r') def remote_uname(): #定义一个远程任务的函数 run('uname -r') def uname(): #定义一个函数,将本地与远端组合起来使用 local_uname() remote_uname() 查看列表 from fabric.api import * @runs_once #一定要指定这一条,否则会让你输入多次路径 def input(): return prompt("input path:") #prompt函数,让用户输入自己想要的路径,将输入的值返回到函数。 def ls_path(dirname): #在定义函数的时候指定形参。 run("ls -l "+dirname) def go(): ls_path(input()) #使用input返回的值,用于ls_path()的参数 处理异常 from fabric.api import * from fabric.contrib.console import * #这个模块中包含confirm def backup(): with settings(warn_only=True): #with命令表示执行这句后,执行下面的命令。使用settings命令来设置警告模式 state=local('mkdir /root/zz') #创建一个文件夹 if state.failed and not confirm("/root/zz is already exist,continue?"): #使用failed来判断state这条命令是否失败,失败了为真。confirm向用户确认是否继续,继续为真。如果命令失败了,并且用户希望停止,便通过if判断。 abort("退出任务") #abort是退出任务,有些类似python的exit。退出并且时返回给用户一串字符串 local('tar cavf /root/zz/etc.tar.gz /etc') #将etc的文件备份到/root/zz文件夹中 并行执行与顺序执行 @parallel #将下面的函数设为并行执行。 def runs_parallel(): run('uname -r') @serial #将下面的函数设为顺序执行(默认即为顺序执行 ) def runs_serially(): pass @parallel(pool_size=5) #将下面的函数设为并行执行,并且限制最多5个线程。 def runs_parallel(): pass

优秀的个人博客,低调大师

微信小程序输入地址自动获取经纬度

腾讯位置服务官网:http://lbs.qq.com/index.html SDK下载地址:http://3gimg.qq.com/lightmap/xcx/jssdk/qqmap-wx-jssdk1.0.zip 微信小程序JavaScript SDK文档地址:http://lbs.qq.com/qqmap_wx_jssdk/index.html 地址解析坐标API文档地址:http://lbs.qq.com/qqmap_wx_jssdk/method-geocoder.html 申请密钥(key)这里就不讲了。 1、选择SDK为微信小程序JavaScript SDK 微信小程序JavaScript SDK 2、下载SDK,下载完后解压,把下载的包解压并复制文件到项目文件夹。 下载SDK 制文件到项目文件夹 3、到要使用的页面js引入SDK文件,并实例化API核心类 // 引入SDK核心类 import QQMapWX from 'xxx/qqmap-wx.js'; // 实例化API核心类 let qqMap = new QQMapWX({ key: '开发密钥(key)' // 必填 }); 4、当用户输入地址完毕后解析坐标 <input type="text" bindblur="atuoGetLocation" /> atuoGetLocation(e) { qqMap.geocoder({ address: e.detail.value, //用户输入的地址(注:地址中请包含城市名称,否则会影响解析效果),如:'北京市海淀区彩和坊路海淀西大街74号' complete: res => { console.log(res.result.location); //经纬度对象 } else { console.log('无法定位到该地址,请确认地址信息!'); } } }); } API使用详情请参考地址解析坐标API文档地址:http://lbs.qq.com/qqmap_wx_jssdk/method-geocoder.html

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册