2018

之前写了几篇关于Spring Cloud Stream使用中的常见问题,比如: 如何处理消息重复消费 如何消费自己生产的消息 下面几天就集中来详细聊聊,当消息消费失败之后该如何处理的几种方式。不过不论哪种方式,都需要与具体业务结合,解决不同业务场景可能出现的问题。 今天第一节,介绍一下Spring Cloud Stream中默认就已经配置了的一个异常解决方案:重试! 应用场景依然要明确一点,任何解决方案都要结合具体的业务实现来确定,不要有了锤子看什么问题都是钉子。那么重试可以解决什么问题呢?由于重试的基础逻辑并不会改变,所以通常重试只能解决因环境不稳定等外在因素导致的失败情况,比如:当我们接收到某个消息之后,需要调用一个外部的Web Service做一些事情,这个时候如果与外部系统的网络出现了抖动,导致调用失败而抛出异常。这个时候,通过重试消息消费的具体逻辑,可能在下一次调用的时...

在上一篇《Spring Cloud Stream如何处理消息重复消费》中,我们通过消费组的配置解决了多实例部署情况下消息重复消费这一入门时的常见问题。本文将继续说说在另外一个被经常问到的问题:如果微服务生产的消息自己也想要消费一份,应该如何实现呢? 常见错误在放出标准答案前,先放出一个常见的错误姿势和告警信息(以便您可以通过搜索引擎找到这里^_^)。以下错误基于Spring Boot 2.0.5、Spring Cloud Finchley SR1。 首先,根据入门示例,为了生产和消费消息,需要定义两个通道:一个输入、一个输出。比如下面这样: public interface TestTopic { String OUTPUT = "example-topic"; String INPUT = "example-topic"; @Output(OUTPUT)...

从2016年起就开始接触Consul,使用的主要目的就是做服务发现,后来逐步应用于生产环境,并总结了少许使用经验。最开始使用Consul的人不多,为了方便交流创建了一个QQ群(群号在最后),这两年微服务越来越火,使用Consul的人也越来越多,目前群里已有400多人,经常有人问一些问题,比如: 服务注册到节点后,其他节点为什么没有同步? Client是干什么的?(Client有什么作用?) 能不能直接注册到Server?(是否只有Server节点就够了?) 服务信息是保存在哪里的? 如果节点挂了健康检查能不能转移到别的节点? 有些人可能对服务注册和发现还没有概念,有些人可能使用过其它服务发现的工具,比如zookeeper,etcd,会有一些先入为主的经验。这篇文章将结合Consul的官方文档和自己的实际经验,谈一下Consul做服务发现的方式,文中尽量不依赖具体的框架和开发语言,...

可能看到这个标题,读者会问:要修改日志的级别,不是直接修改log.xxx就好了吗?为何要搞那么复杂呢?所以,先说一下场景,为什么要通过TurboFilter去动态的修改日志级别。我们在使用Java开发各种项目的时候必然的会引入很多框架,这些框架通过堆叠的方式完成所要提供的业务服务(一个服务请求在进入后会在这些框架中兜一圈,然后返回结果),当一个比较底层的框架在处理过程中抛出了异常之后,这个异常会不断的向上传递。这个时候,有的框架直接throw,继续向上抛,而有的在throw之前还会自己打印一下error日志,这就导致了当出现异常的时候,往往会出现一连串类似的错误日志记录。如果对接了错误日志告警,就会出现重复告警的现象。为了解决类似这样的问题,修改源码重新编译最直接,但是不可取。所以希望可以有更好的手段去控制这些已经被编码固化的日志打印信息。当我们使用Logback的时候,TurboF...

当我们需要对日志的打印要做一些范围的控制的时候,通常都是通过为各个Appender设置不同的Filter配置来实现。在Logback中自带了两个过滤器实现:ch.qos.logback.classic.filter.LevelFilter和ch.qos.logback.classic.filter.ThresholdFilter,用户可以根据需要来配置一些简单的过滤规则,下面先简单介绍一下这两个原生的基础过滤器。 ch.qos.logback.classic.filter.LevelFilter过滤器的作用是通过比较日志级别来控制日志输出。下面是一个只记录日志级别为ERROR的例子: <appender name="ERROR_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender"> <...

最近收到好几个类似的问题:使用Spring Cloud Stream操作RabbitMQ或Kafka的时候,出现消息重复消费的问题。通过沟通与排查下来主要还是用户对消费组的认识不够。其实,在之前的博文以及《Spring Cloud微服务实战》一书中都有提到关于消费组的概念以及作用。 那么什么是消费组呢?为什么要用消费组?它解决什么问题呢?摘录一段之前博文的内容,来解答这些疑问: 通常在生产环境,我们的每个服务都不会以单节点的方式运行在生产环境,当同一个服务启动多个实例的时候,这些实例都会绑定到同一个消息通道的目标主题(Topic)上。默认情况下,当生产者发出一条消息到绑定通道上,这条消息会产生多个副本被每个消费者实例接收和处理(出现上述重复消费问题)。但是有些业务场景之下,我们希望生产者产生的消息只被其中一个实例消费,这个时候我们需要为这些消费者设置消费组来实现这样的功能。 详细...

现在用Swagger来生成API文档的例子已经非常多了,今天碰到开发同事问了一个问题,帮着看了一下,主要还是配置方法的问题,所以记录一下。如果您也碰到了同样的问题,希望本文对您有用。 问题描述@ApiModelProperty注解是用来给属性标注说明、默认值、是否可以为空等配置使用的,其中有一个属性allowableValues是本文要讲的重点,从属性命名上就能知道,该属性用来配置所标注字段允许的可选值。 但是这个属性是一个String类型,我们要如何配置可选值呢? 我们可以通过源码的注释了解到一切: public @interface ApiModelProperty { /** * Limits the acceptable values for this parameter. * <p> * There are three w...

在之前的所有Spring Boot教程中,我们都只提到和用到了针对HTML和JSON格式的请求与响应处理。那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式返回一个对象呢? 实现原理:消息转换器(Message Converter)在扩展上述问题之前,我们先要知道Spring Boot中处理HTTP请求的实现是采用的Spring MVC。而在Spring MVC中有一个消息转换器这个概念,它主要负责处理各种不同格式的请求数据进行处理,并包转换成对象,以提供更好的编程体验。 在Spring MVC中定义了HttpMessageConverter接口,抽象了消息转换器对类型的判断、对读写的判断与操作,具体可见如下定义: public interface HttpMessageConverter<T> { boolea...

由于Spring Cloud对Etcd的支持一直没能从孵化器中出来,所以目前来说大多用户还在使用Eureka和Consul,之前又因为Eureka 2.0不在开源的消息,外加一些博眼球的标题党媒体使得Eureka的用户有所减少,所以,相信在选择Spring Cloud的用户群体中,应该有不少用户会选择Consul来做服务注册与发现。 本文就来说一下,当我们使用Spring Cloud最新的Finchley版 + Consul 1.2.x时候最严重的一个坑:多实例注册的问题。 问题解读问题:该问题可能在开发阶段不一定会发现,但是在线上部署多实例的时候,将会发现Consul中只有一个实例。 原因:造成该问题的主要原因是Spring Cloud Consul在注册的时候实例名(InstanceId)采用了:“服务名-端口号”(即:{spring.application.name}-{s...

在前面我们简单介绍了问题类型和工作流的配置方法,今天我们来聊一聊字段和界面这两个互相依赖的家伙。 界面即Issue展示给用户可见的表单页面,分为创建界面、查看界面和编辑界面。而界面上存在的表单项则称为字段,可以设置这些项是数字、文字、还是图片,以及这些项在界面中是必选、可选,或者是隐藏。 这两个家伙是相互强影响的,因此在这一篇中一起介绍。 * 注:以下配置基于 JIRA 7.1.9 字段我们已经知道如何在项目中建立问题类型和设置这些问题类型的工作流,但是这些问题的状态和内容如何清晰的展示给用户呢? 比如创建问题的时候,界面需要展示哪些内容来明确标识问题的相关信息?选择问题类型之后,如何表述问题的具体内容?所属模块、解决版本等信息都在哪体现呢?这些都需要通过界面和字段进行定义。 当我们创建界面时,需要规定这个界面上显示给用户可见的字段信息,这些字段信息需要预先进行定义。 1.1 创...

在项目管理中Jira占据着大佬的地位,很大部分原因要归功于他强大的工作流支持,你可以完全根据自己的企业和团队习惯自定义工作流内容,包括步骤、流转、条件和权限等等。 今天我们就来看看Jira工作流要如何配置吧。 * 注:以下配置基于 JIRA 7.1.9 工作流在上一篇文章中,我们新建了一个问题类型,并且增加到问题类型方案里了,同时又关联到我们的这个项目中。那么这些问题我们需要如何设置流程走向来表示问题的处理过程呢?这就需要设定一个流程,并将这个流程引用到这个问题类型中。 1.1 新建工作流具有系统管理权限的人员登录进入问题管理中,在左导航中选择工作流。 我们可点击增加工作流,在弹出的对话框中,输入名称,点击增加按钮即可 点击增加按钮后跳转到工作流详细设计界面。 我们这里先简单的介绍如何创建工作流,由于不同的使用场景工作流的配置也会不同,内容较多,设计的场景也各有式各样。 我们先...

最近在工作中频繁接触Jira,从一脸懵逼的小白摸索成为一个准管理员,爬了不少坑,特此整理如下,望有助于在座各位~ * 注:以下配置基于 JIRA 7.1.9 项目管理新建项目后首先需要配置的内容包括:问题类型方案、工作流配置方案、字段配置方案、问题类型界面方案,一般完成这四个配置项目即可使用,如果还需要其它的,可以继续配置这个项目的权限、问题安全方案、通知方案等,还包括其它管理内容,如模块、项目角色。 这里先说明问题类型方案、工作流配置方案、字段配置方案、问题类型界面方案的配置规范。 下面是项目和问题类型、界面、工作流、字段之间的相互关系图: 1.1 创建项目一个项目是对一系列相关问题的综合管理。在Jira 中,可以通过以下方式创建项目。首先,需要具有项目创建权限的人登录后台管理界面,然后选择项目,通过创建项目按钮进入到项目创建的界面。 进入到项目管理界...

最近一致在更新Spring Cloud Config的相关内容,主要也是为这篇埋个伏笔,相信不少调研过Spring Cloud Config的用户都会吐槽它的管理能力太弱。因此,就有了下面为讲推荐的这个开源项目,希望对已经入坑Spring Cloud Config的童鞋们有所帮助! 简介在Spring Cloud的微服务架构方案中虽然提供了Spring Cloud Config来担任配置中心的角色,但是该项目的功能在配置的管理层面还是非常欠缺的。初期我们可以依赖选取的配置存储系统(比如:Gitlab、Github)给我们提供的配置管理界面来操作所有的配置信息,但是这样的管理还是非常粗粒度的,因此这个项目的目的就是解决这个问题,通过此项目,我们将提供一套基于Spring Cloud Config配置中心的可视化管理系统。 在该项目中,我们对于服务治理、配置存储、可视化操作都做了抽象...

介绍在今年5月中,Netflix终于开源了它的支持异步调用模式的Zuul网关2.0版本,真可谓千呼万唤始出来。从Netflix的官方博文[附录1]中,我们获得的信息也比较令人振奋: The Cloud Gateway team at Netflix runs and operates more than 80 clusters of Zuul 2, sending traffic to about 100 (and growing) backend service clusters which amounts to more than 1 million requests per second. Netflix部署了超过80+的Zuul2云网关集群,流量经过Zuul2集群被路由到后端超过100+的微服务,且每秒钟经过Zuul2集群的请求超过100万。 Zuul2看起来很强大,支持...

一直是 ESLint 的忠实用户,深知规范的重要性。然而,在新项目交接中,我被 Git Commit 规范逼疯了。才意识到自己的疏忽,于是便有了一探究竟的想法。 一、为什么需要规范?无规矩不成方圆,编程也一样。 如果你有一个项目,从始至终都是自己写,那么你想怎么写都可以,没有人可以干预你。可是如果在团队协作中,大家都张扬个性,那么代码将会是一团糟,好好的项目就被糟践了。不管是开发还是日后维护,都将是灾难。 这时候,有人提出了何不统一标准,大家都按照这个标准来。于是 ESLint,JSHint 等代码工具如雨后春笋般涌现,成为了项目构建的必备良品。 Git Commit 规范可能并没有那么夸张,但如果你在版本回退的时候看到一大段糟心的 Commit,恐怕会懊恼不已吧。所以,严格遵守规范,利人利己。 二、具体规则先来看看公式: <type>(<scope>): &...