单体应用架构和微服务架构的区别
单体应用体构(一个项目打成一个包部署到一台服务器 )
缺点:
代码复杂性高,一个项目可能包含上百万代码
技术更新难
项目版本迭代频率低
扩展性低,只能垂直扩展(提升硬件)
可靠性低,一个bug导致整个程序崩溃
性能较低,项目包太大,请求和响应时间长
微服务架构(多个小项目打成多个包部署到多台服务器)
优势:
单个项目的复杂性降低
项目技术更新容易
版本迭代频率提升
扩展性提升,可以水平扩展(加机器)
可靠性提升,一个服务出问题,其它可以继续访问
性能提升,项目小了,反应更快
缺点:
成本更高,多台服务器
整体项目的复杂性大大提升
运维更难
SpringCloud框架
开发微服务的架构
zookeeper + dubbo 比较早的架构,很多需要自己搭建
SpringCloud 目前比较成熟的框架,功能比较全面,开发更加容易
主要的组件
注册中心,服务的注册和发现机制,Eureka、Nacos、Zookeeper等
配置中心,集中管理服务的配置文件,Config、Nacos
API网关,实现路由和权限管理,Zuul、Gateway
服务通信,实现Restful的服务调用,Openfeign、Dubbo
负载均衡,平衡每个服务的负载量,Ribbon
熔断器,提高系统的可靠性,Hystrix、Sentinel
分布式事务,全局事务管理多个服务,Seata
SpringCloud( 基于SpringBoot)
主要框架体系:
Neflix(网飞,全球最大的流媒体互联网企业)
Eureka、Ribbon、Hystrix、Zuul
Alibaba
Nacos、Sentinel、Seata、RocketMQ
注册中心
注册中心解决了什么问题:
由于微服务之间相互通信,需要通过Ip和端口,Ip和端口又是写死在程序代码上,所以会出现问题,首先遇到服务的Ip和端口发生改变,调用会出现错误,再者无法实现集群部署。
注册中心Eureka
服务的提供者和服务的消费者都在注册中心上注册(保存IP和端口),服务消费者调用服务提供者时通过注册中心查找对方服务器的IP和端口,进行通信
1.提供者将IP和端口注册到注册中心
2.注册中心和提供者每隔一段时间(60s)发送心跳包
3.如果一段时间(90s)没有收到心跳,注册中心就会将服务剔除
4.消费者需要调用提供者时,会到注册中心上查找,注册中心提供服务清单
5.消费者通过服务清单中的IP和端口来调用提供者
6.服务清单每隔一段时间(30s)更新一次
例子:就像消费者平时的滴滴打车,通过第三方平台获取到司机和用户的数据,首先注册中心给司机师傅发送心跳包,看看司机是否还在工作,正常的话则会得到反馈,超过时间为反馈的话,则会被平台剔除(判定为已不再工作),而消费者需要使用滴滴时候,平台会提供司机们的服务清单,来调用司机们,最后平台再观察服务清单的更新。
搭建Eureka服务器
1.继承父项目
2.引入eureka服务器的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>3.在启动类上加 @EnableEurekaServer
4.编写配置文件
server.port=8888 spring.application.name=eureka-server eureka.instance.hostname=127.0.0.1 # 是否注册到Eureka上,false 本身就是服务器 eureka.client.register-with-eureka=false # 是否拉取服务清单,false eureka.client.fetch-registry=false # 服务的地址配置 eureka.client.serviceUrl.defaultZone=http: //${eureka.instance.hostname}:${server.port}/eureka/
配置Eureka客户端
1.导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>2.启动类上加 @EnableEurekaClient
3.配置文件
server.port=8002 # 服务名称 spring.application.name=order-service # 是否注册到Eureka上 eureka.client.register-with-eureka=true # 是否拉取服务清单,false eureka.client.fetch-registry=true # 服务的地址配置 eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8888/eureka/
4.修改RestTemplate的配置
@Configuration public class RestTemplateConfig { @LoadBalanced @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
5.修改调用服务的代码
restTemplate.getForEntity("http://product-service/product/8", Product.class);
Eureka的自动保护机制
Eureka默认情况下启动自动保护机制,避免短时间内大面积服务掉线(15分钟内85%服务)导致服务被大量剔除,网络恢复后服务无法正常调用,自动保护机制会将服务清单保护起来,不进行剔除。会判定为是自己的责任,所以会保护起来,不会进行剔除。
推荐在生产环境使用自我保护机制,开发时可以关闭
Eureka的集群配置
优点:提高注册中心的可用性,一个挂了其它的可以用
实际作用:增加Eureka服务器,让它们相互注册,所有客户端注册到所有注册中心上
两个服务的配置:
application-server1.properties server.port=8888 spring.application.name=eureka-server eureka.instance.hostname=127.0.0.1 # 是否注册到Eureka上,true 服务器注册到其它Eureka上 eureka.client.register-with-eureka=true # 是否拉取服务清单,true eureka.client.fetch-registry=true # 服务的地址配置 eureka.client.serviceUrl.defaultZone=http://127.0.0.1:7777/eureka/ # 自我保护机制 false关闭 eureka.server.enable-self-preservation=false application-server2.properties server.port=7777 spring.application.name=eureka-server eureka.instance.hostname=127.0.0.1 # 是否注册到Eureka上 eureka.client.register-with-eureka=true # 是否拉取服务清单 eureka.client.fetch-registry=true # 服务的地址配置 eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8888/eureka/ # 自我保护机制 false关闭 eureka.server.enable-self-preservation=false
注意:创建两个启动配置
客户端注册:eureka.client.serviceUrl.defaultZone=http:
//127.0.0.1:8888/eureka/,http://127.0.0.1:7777/eureka/