项目背景

随着业务的剧增,从运营成本,代码维护,bug率,发布更新等多个维度考虑,现有的项目都不得不考虑重构了,因为是盈利项目,客户群体还是比较大,重构和线上正常的更新迭代工作要同步进行,版本迭代就不说了,就说说重构的部分

前期计划

从外往内逐步剥离,先剥离出来基础的业务类型,耦合度不高的,比如短信,物流查询,消息模板等第三方服务,工具类功能业务,营销推广模块(海报生成,h5页面),店铺装修,推广素材,数据中心,导出,等相关的外围业务,像商品,订单,会员,财务,支付,系统配置,服务市场,权限管理等这种业务耦合度比较高的,放到后期

微服务治理选型

SpringCloud和SpringCloudAlibaba 之间选一个,SpringCloudAlibaba 也是在SpringCloud项目上孵化的,实际上对SpringCloud实现拓展组件功能,下面是我整理的区别

SpringCloud

SpringCloudAlibaba

注册中心

Netflix Eureka

Nacos

配置中心

SpringCloudConfig

Nacos

消息中间件

无(第三方替代方案:Rabbitmq)

RecketMQ

分布式事务解决方案

无(第三方替代方案:2pc

Seata

熔断降级

Hystrix

Sentinel

分布式调度任务

无(第三方替代方案:xxl-job)

Alibaba Cloud SchedulerX

服务网关

Zuul

(不是阿里的)Spring Cloud Gateway

服务调用

OpenFeign

Dubbo

Eureka VS Nacos

Nacos

Eureka

一致性协议(CAP)

CP+AP

AP

健康检查

TCP/HTTP/MYSQL/Client Beat

Client Beat

负载均衡策略

权重/metadata/Selector

Ribbon

雪崩保护



自动注销实例

支持

支持

访问协议

HTTP/DNS

HTTP

多数据中心

支持

支持

跨注册中心同步

支持

支持

K8S集成

支持

不支持

维护状态

在更(而且很快)

停更

集成配置中心

支持

不支持

资源隔离

支持

不支持

Nacos是阿里开源的,Nacos 支持基于 DNS 和基于 RPC 的服务发现。在Spring Cloud中使用Nacos,只需要先下载 Nacos 并启动 Nacos server,Nacos只需要简单的配置就可以完成服务的注册发现。
Nacos除了服务的注册发现之外,还支持动态配置服务。动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易
Nacos 可以与 Spring, Spring Boot, Spring Cloud 集成,并能代替 Spring Cloud Eureka, Spring Cloud Config。

Rabbitmq VS RecketMQ

Rabbitmq

RecketMQ

支持语言

语言无关

只支持JVA

单机吞吐量

万级

万级

消息延迟

微秒级

毫秒级

消息丢失


理论上是不丢失

消息重复

可控制


社区活跃



商家支持


阿里

特点

由于是Erlang语言的比发能,性能很好

分布式扩展设计,主从HA,支持上万个队列,多种消费模式,性能好

持久化

内存,文件

磁盘

可视化


有web console实现

事务消息


半开消息模式 支持本地事务

RocketMQ阿里商业有支持,少了维护成本,接入方便,而且是经过双十一考验的,可以大量堆积消息在broker中,支持本地事务消息

Sentinel VS Hystrix

Sentinel

Hystrix

隔离策略

基于比发数

线程池隔离/信号量隔离

熔断降级策略

基于响应时间或失败率

基于失败率

规则配置

多数据源

多数据源

扩展性

多扩展

插件形式

调用链路信息

支持

不支持

注解

支持

支持

限流

QPS/比发数/调用关系的限流

不支持

流量整形

支持慢启动,匀速模式

不支持

系统负载保护

支持

不支持

控制台

开箱即用,可配置规则,查看秒级监控,机器发现等

不完善

是否维护

持续更新

停更

Sentinel 这个确实很强大,也是阿里开源的,接入也方便,是面向分布式架构的流量控件,主要以流量切入点,从流量控制,熔断降级,系统自适应保护等多维度保障服务的稳定性,比如流量规则,降级规则,热点规则,系统规则,授权规则

Zuul VS Gateway

Zuul

Gateway

实现

基于Servlet2.X构建,使用阻塞API

基于Spring 5推出的响应式Web框架,使用非阻塞API

长连接

不支持(2.0是基于Netty,也是非阻塞的,支持长连接)

支持

限流

不支持

内置了限流过滤器

集成Sentinel



社区活跃


很高

上手难度

同步编程,上手简单

门槛高

Gateway在性能要好过Zuul,因为是Spring webflux 有一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的、非堵塞的、事件驱动的服务,在伸缩性方面表现非常好。使用非阻塞API。 Websockets得到支持,并且由于它与Spring紧密集成,所以将会是一个更好的 开发 体验,并且项目选择SpringCloud生态组件的话,Spring Cloud Gateway相比而言更加具备优势,单从流式编程+支持异步上就足以让开发者选择它了。
对于小型微服务架构或是复杂架构(不仅包括微服务应用还有其他非Spring Cloud服务节点),zuul也是一个不错的选择

Seata

Seata 也是阿里开源分布式事务治理的方案,接入方便,经历双十一的考验,模式多样化,提供AT、TCC、SAGA 和 XA 事务模式,支持高可用,之后章节详细讲解这几种模式的区别

认证

JWT 做为登录凭证

优点

因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用。
因为有了payload部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息。
便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。
它不需要在服务端保存会话信息, 所以它易于应用的扩展。

授权

后期有认证授权相关服务 单独处理

ORM

Mybatis-Plus 简称 (MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生

优点

无侵入:引入它不会对现有工程产生影响
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎
实现乐观锁插件:数据版本控制,防止更新出现脏数据

缓存

Redis 这个没啥说的 现在是主流

数据库

Mysql 也是没啥说的 开源 免费 主流

搜索引擎

Elasticsearch

Elasticsearch 分布式的海量数据搜索与分析的技术,适合进行大数据场景下的数据分析应用
优点:
分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。
实时分析的分布式搜索引擎。
可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据
缺点:还不够自动(不适合当前新的Index Warmup API)

Solr

Solr 是Apache Lucene项目的开源企业搜索平台。其主要功能包括全文检索、命中标示、分面搜索、动态聚类、数据库集成,以及富文本(如Word、PDF)的处理。Solr是高度可扩展的,并提供了分布式搜索和索引复制
优点:
Solr有一个更大、更成熟的用户、开发和贡献者社区。
支持添加多种格式的索引,如:HTML、PDF、微软 Office 系列软件格式以及 JSON、XML、CSV 等纯文本格式。
Solr比较成熟、稳定。
不考虑建索引的同时进行搜索,速度更快
缺点:
建立索引时,搜索效率下降,实时索引搜索效率不高
当实时建立索引时, Solr会产生io阻塞,查询性能较差

分布式锁

Etcd 是CoreOS团队于2013年6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库。etcd内部采用raft协议作为一致性算法,etcd基于Go语言实现

优点

简单:安装配置简单,而且提供了HTTP API进行交互,使用也很简单
安全:支持SSL证书验证
快速:根据官方提供的benchmark数据,单实例支持每秒2k+读操作
可靠:采用raft算法,实现分布式系统数据的可用性和一致性
分布式锁实现原理:
1.raft
raft,是工程上使用较为广泛,强一致性、去中心化、高可用的分布式协议。
raft提供了分布式系统的可靠性功能。
2.lease功能
lease功能,就是租约机制(time to live)。
1、etcd可以对存储key-value的数据设置租约,也就是给key-value设置一个过期时间,当租约到期,key-value将会失效而被etcd删除。
2、etcd同时也支持续约租期,可以通过客户端在租约到期之间续约,以避免key-value失效;
3、etcd还支持解约,一旦解约,与该租约绑定的key-value将会失效而删除。
Lease 功能可以保证分布式锁的安全性,为锁对应的 key 配置租约,即使锁的持有者因故障而不能主动释放锁,锁也会因租约到期而自动释放。
3.watch功能
监听功能。watch 机制支持监听某个固定的key,它也支持watch一个范围(前缀机制),当被watch的key或范围发生变化时,客户端将收到通知。
在实现分布式锁时,如果抢锁失败,可通过 Prefix 机制返回的 KeyValue 列表获得 Revision 比自己小且相差最小的 key(称为 pre-key),对 pre-key 进行监听,因为只有它释放锁,自己才能获得锁,如果 Watch 到 pre-key 的 DELETE 事件,则说明pre-ke已经释放,自己已经持有锁。
4.prefix功能
前缀机制。也称目录机制,如两个 key 命名如下:key1=“/mykey/key1″ , key2=”/mykey/key2″,那么,可以通过前缀-“/mykey”查询,返回包含两个 key-value 对的列表。可以和前面的watch功能配合使用。
例如,一个名为 /mylock 的锁,两个争抢它的客户端进行写操作,实际写入的 key 分别为:key1=”/mylock/UUID1″,key2=”/mylock/UUID2″,其中,UUID 表示全局唯一的 ID,确保两个 key 的唯一性。很显然,写操作都会成功,但返回的 Revision 不一样,那么,如何判断谁获得了锁呢?通过前缀 /mylock 查询,返回包含两个 key-value 对的的 KeyValue 列表,同时也包含它们的 Revision,通过 Revision 大小,客户端可以判断自己是否获得锁,如果抢锁失败,则等待锁释放(对应的 key 被删除或者租约过期),然后再判断自己是否可以获得锁。
lease 功能和 prefix功能,能解决上面的死锁问题。
5.revision功能
每个 key 带有一个 Revision 号,每进行一次事务加一,因此它是全局唯一的,如初始值为 0,进行一次 put(key, value),key 的 Revision 变为 1;同样的操作,再进行一次,Revision 变为 2;换成 key1 进行 put(key1, value) 操作,Revision 将变为 3。
这种机制有一个作用:
通过 Revision 的大小就可以知道进行写操作的顺序。在实现分布式锁时,多个客户端同时抢锁,根据 Revision 号大小依次获得锁,可以避免 “羊群效应” (也称 “惊群效应”),实现公平锁。

日志

@Slf4j
ELK(Elasticsearch,Logstash,Kibana),可视化日志查找

优点

阿里巴巴Java开发手册》关于日志章节专门提到:
【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架
SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Abc.class)7

链路追踪(APM)

SkyWalking 又是一个优秀的国产开源框架,2015年由个人吴晟(华为开发者)开源 , 2017年加入Apache孵化器。
skywalking是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。SkyWalking 是观察性分析平台和应用性能管理系统。提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案(官网介绍)

优点

多语言自动探针
支持警告
优秀的可视化方案
轻量高效,对代码无侵入性。对于微服务,支持dubbo,SpringBoot,SpringCloud集成

分布式任务

xxx-job 是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用

优点

上手简单,有可视化页面。对任务进行CRUD操作
支持动态修改任务状态、启动/停止任务,以及终止运行中任务,即时生效
任务分布式执行,任务"执行器"支持集群部署,可保证任务执行HA
执行器集群部署时提供丰富的路由策略,包括:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移、忙碌转移等
支持实时监控任务进度
调度中心”通过DB锁保证集群分布式调度的一致性, 一次任务调度只会触发一次执行
调度线程池进行隔离拆分,慢任务自动降级进入"Slow"线程池,避免耗尽调度线程,提高系统稳定性
提供官方docker镜像,并实时更新推送dockerhub,进一步实现产品开箱即用

总结

传统架构

优点:开发快 ,运维和开发人员成本低,适合前期快速上线项目
缺点:随着业务增长,代码维护难,业务划分不明确,扩展难,应用复杂性,故障级联,效率低

微服务

优点:高内聚,低耦合
高度自治:开发,测试,构建,部署,运行,发布,弹性扩展<无状态化>
弹性设计<容错,隔离,降级>
自动化,持续集成,持续交付
缺点:开发和运维成本高,分布式事务处理困难

下期分享系统之间分层和规范

传送门