Spring Boot micro electric service providers to develop practical projects --- distributed development to avoid those pits

Has entered the seventh speak today, the whole set up micro-services architecture work has been largely completed. So far those that actually use the technology and to achieve what functions? Let's recap.

Technology used: SpringBoot, Dubbo, Zookeeper, Redis, Kafka used to live

Realization of functions:

1, Maven parent-child project, to achieve a sub-environment deployment configuration and port services unified configuration

2, the integrated access Dubbo, sub-module for the service layer, the provider (four) and consumers (a) configuration and service calls, micro landing service implementation.

3, Maven sub-module project (the interface and service layer) version number of the unified configuration management implementation.

4, Redis access, single sign-on and distributed cache implementation.

5, security interfaces, token, signature algorithm and sprinkle salt, filters signature, and interception token verification process.

6, global exception handler, Aop log printing, anti-SQL injection interception processing implementation.

See these full of dry goods, I do not know yet satisfied with the recent series of articles I do? Next, I will continue in-depth, and slowly explore and explain the truth to achieve technology and micro-electric business service behind it.

Currently the project modules are as follows:

So far, only achieved four micro-services (providers) to combat demonstration project, with the latter gradually in-depth, micro-services will continue to increase. Today, I want to talk about those projects in their own pit distributed stepped on.

1, an entity serialization problem

If you did not do distributed development of small partners, there must have to pay attention, if you project entity is not serialized, it will cause the remote procedure call can not be achieved when consumers return to the receiving service provider entity will throw abnormal.

Why must serialize it? Some might say that I had to do the project, entities are not serialized good thing not running. That's because your project before all the code in a Web container to run, that is to say: the whole project before you in a JVM inside.

但分布式项目就不一样了,提供者和消费者是在不同的web容器里运行(不同的JVM)。消费者在进行远程方法调用时,实际就是消费者的jvm在调用提供者jvm里的对象,但这个对象在消费者的jvm里并不存在,那要获取就得用Java对象序列化来解决。简而言之:序列化的作用就是为了不同jvm之间共享实例对象的一种解决方案

2,分布式环境生成编号问题

这是我在项目中真真实实跳过的坑,根据之前多年项目的开发经验,一般编号(客户,商品、订单等编号)的生成规则基本都是借助于数据库的自增id实现,看似本来通用的解决方案,在分布式项目中,竟然是给自己埋坑。

之前的编号实现方式:在添加数据方法的Service实现里,先查询获得数据库最大ID对应的编号,然后给这个编号+1生成新编号作为当前新增数据的编号插入数据库。开始看着很完美,但后来突然有人反映编号重复,这就奇怪了?加班趴着debug代码,但就是找不出来问题的原因。面对这种突如其来的问题完全不知所措,不得不求助网络,各种搜索后才明白,是提供者集群惹的祸。

原因分析:当两个及以上并发请求同时进入集群中的不同提供者时,一个提供者的Service实现在生成编号并插入数据之前,另一个提供者的Service也查询了数据库并获取了跟前一个提供者获取相同的最大编号。导致两台服务最终生成的编号相同。那可能也有人说了,你先插入数据,然后根据插入数据生成的自增id再去生成编号更新数据库不就解决了。但你有没想过,更新数据库操作需要锁表,在高并发请求的情况下,这会造成很大的性能瓶颈。

目前流行的解决方案:雪花算法,是完全基于代码实现,不依赖数据库。

上图只是部分代码,我们看到这个工具类实现了单例模式,生成的编号是:时间(到毫秒)+ ip(后面取了4位) +  自增序列。

我来演示下效果吧,先写个main方法实例化工具类,并写for循环生成编号

我红框圈出来的,是在同一时间,虽然时间和四位ip相同,但后三位的自增序列值一直在递增。那如果服务端做集群呢,是不是编号又会重复?就算在同一时间的高并发请求,几个服务终端可能会生成时间相同、后三位序列号相同的编号,但是,不同终端通过ip最后获取的四位值肯定不同。所以不可能有重复出现。

3,日志统一打印问题

分布式环境中,如果每个服务的日志分散到各自服务所在机器上,那么以后如果线上出现异常或日志收集及分析检查时,会让你痛苦不已,集群和服务规模小还好,特别是在负载均衡后的多个服务实例,你无法确定某个请求被谁接收了,所以只能翻看每个实例的日志。

处理方案:Service业务实现层不要捕获异常,直接通过throws全部往外抛。

然后在接口层在做相应的统一处理,比如Aop里打印,或使用日志框架(如:ELK)统一收集等。这样如果你的服务层做了集群,线上报错你也不用纠结去哪个服务器看服务提供者的日志,你只要到对应接口层服务查看输出的日志或统一收集的地方去查看。

获取项目源代码,请扫码关注公众号,并发送Springboot获取。

 

Guess you like

Origin www.cnblogs.com/lyn20141231/p/11210342.html