微服务核心就是把传统的单机应用,根据业务将单机应用拆分为一个一个的服务,彻底的解耦,每一个服务都是提供特定的功能,一个服务只做一件事,类似进程,每个服务都能够单独部署,甚至可以拥有自己的数据库。这样的一个一个的小服务就是微服务。
微服务架构是一个架构风格,将一个单一应用程序开发为一组小型服务;每个服务运行在自己的进程中;服务之间通过轻量级的通信机制(http rest api);每个服务都能够独立的部署;每个服务甚至可以拥有自己的数据库。
微服务强调的是服务的大小和对外提供的单一功能,而微服务架构是指把 一个一个的微服务组合管理起来,对外提供一套完整的服务。
1、服务架构
(1)单体架构的扩展
单体架构,当用户增加的时候需要演变为集群架构,每个业务模块都需要扩展包含前端UI,扩展的代价比较高。
微服务架构,当用户增加的时候可以对压力大的模块进行扩展,其他模块不用扩展,这样可以只增加较少的机器。
2. 微服务架构的优缺点
优点
①:每个服务足够小,足够内聚,代码更加容易理解,专注一个业务功能点(对比传统应用,可能改几行代码 需要了解整个系统)
②: 开发简单,一个服务只干一个事情。(加入你做支付服务,你只要了解支付相关代码就可以了)
③: 微服务能够被2-5个人的小团队开发,提高效率
④: 按需伸缩
⑤: 前后端分离, 作为java开发人员,我们只要关系后端接口的安全性以及性能,不要去关注页面的人机交互(H5工程师)根据前后端接口协议,根据入参,返回json的回参
⑥:一个服务可用拥有自己的数据库。也可以多个服务连接同一个数据库
缺点
①:增加了运维人员的工作量,以前只要部署一个war包,现在可能需要部署成百上千
个war包 (k8s+docker+jenkis )
②: 服务之间相互调用,增加通信成本
③:数据一致性问题(分布式事物问题)
④:系能监控等,问题定位..........................
注册中心原理:(订单服务 和 商品服务注册到注册中心,订单服务调用商品服务)
步骤一:订单服务和商品服务启动的时候,都去调用注册中心的注册接口,向注册表中增加记录;
定时任务:TimeTask1 订单服务和商品服务向注册中心定时发送心跳,更新 last_heartTime 字段的时间;
订单服务的 TimeTask2 定时从注册中心拉取 商品服务 的实例IP并存储到订单服务的缓存中(通过Ribbon组件);
TimeTask3 是注册中心的定时任务:定时清理没有心跳的实例信息,将记录的状态修改为 down;
步骤二:订单服务和商品服务在服务关闭的时候,调用注册中心的服务注销接口,从注册表中删除记录;
说明:
注册接口业务逻辑:insert into server_register_table(id,service_name,ip,port,status) values(?,?,?,?)
服务发现接口业务逻辑:select * from server_register_table where service_name='product-server' and status = 'up'
服务心跳接口业务逻辑:update server_register_table set last_heartTime = current_time where service_name='product-server' and ip = '192.168.159.2'
注销接口业务逻辑:delete from server_register_table where service_name = 'order-server' and ip='192.169.158.1'
TaskTimer3的业务逻辑(假设剔除15s没有续约的服务):update server_register_table set status='down' where current_time-last_heartTime>15
(1)spring boot:是用来快速开发微服务的web服务;
(2)spring cloud:是微服务架构的一套工具集;
(3)spring cloud netflix:国外的一个开发微服务的工具集, 是spring cloud的子项目;
(4)spring cloud alibaba:阿里开源的,符合中国企业的一套微服务架构解决方案,也是 spring cloud的子项目;
(1)spring boot 版本选择 (以 2.1.6.RELEASE 版本为例)
2:表示的主版本号,表示是我们的SpringBoot第二代产品
1:表示的是次版本号,增加了一些新的功能但是主体的架构是没有变化的,是兼容的
6:表示的是bug修复版
所以2.1.6合起来就是springboot的第二代版本的第一个小版本的 第6次bug修复版本
RELEASE:存在哪些取值了 ①:snapshot(开发版本) ②:M1...M2(里程碑版本,在正式版发布之前 会出几个里程碑的版本) ③:release(正式版本)
(2)spring cloud的 版本选择
第一代版本:Angle
第二代版本:Brixton
第三代版本:Camden
第四代版本:Edgware
第五代版本:Finchley
第六代版本:GreenWich
第七代版本:Hoxton(还在酝酿中,没正式版本)
这种发布的版本是 以伦敦地铁站发行地铁的站
SNAPSHOT: 快照版本,随时可能修改
M: MileStone,M1表示第1个里程碑版本,一般同时标注PRE,表示预览版版。
RC 版本英文版名字叫Release Candidate(候选版本)一般标注PRE表示预览版
SR: Service Release,SR1表示第1个正式版本,一般同时标注GA:(GenerallyAvailable),表示稳定版本
比如还有一种 RELEASE 版本(正式版本) 比如 Greenwich版本顺序
Greenwich.release -----> 发现bug -----> Greenwich.SR1------> 发现bug----> Greenwich.SR2
服务的提供者 & 服务的消费者是相对的概念,比如用户服务是订单服务的消费者,订单服务是用户服务的提供者。
但是对于 订单服务---->库存服务,那么订单服务就成为服务消费者
(1)在服务消费方调用服务提供方的时候,请求的Ip地址和端口是硬编码的;
(2)若此时,服务提供方的服务(订单服务)部署的机器换了端口或者是更换了部署机器的Ip,那么消费方服务(仓储服务)就要修改代码并重新发布部署;
(3)若服务提供方的服务(订单服务)压力过大,需要将提供服务方的服务(订单服务)作为集群部署,那么意味着订单服务是多节点的,需要运维人员在服务消费方手动维护一份注册表(容易出错)。
(4)当然,有人会说可以使用 nginx 解决 (3)的问题,但是当服务出现了成百上千的时候,nginx 的配置文件就太大太复杂了;