微服务个人感觉就是把一个业务系统拆分成多个系统进行开发,单一职责。引入提供者和消费者两个概念,由于把一个业务系统进行拆分,降低了耦合,就难免需要相互调用。A系统调用B系统的时候,A称作消费者,B称为提供者。
1.Eureka注册中心
服务提供者和消费者之间的互动,采用http请求的方式。
1.如果采用硬编码的方式写死在系统中,每次环境的改变都需要重写ip;
2.做成可配置,用配置数据库进行管理,但是每次换环境也需要修改配置比较麻烦;
所以最后采用eureka注册中心,自动注册获取相关信息
优势:
1.并发量高的时候,可以实现负载均衡。
2.每隔30s心跳获取健康状态
1.1搭建注册中心
1.1.1新建微服务module
1.1.2引入依赖
由于我这里父工程有版本,所以这里就没写版本。
<dependencies>
<!--Eureka服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
1.1.3创建服务启动类
springboot项目都需要启动类,除了通用的还要加个@EnableEurekaServer作为服务开关。
package com.mt.eureka;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* 类描述:Eureka服务启动类
*
* @ClassName EurekaApplication
* @Author ward
* @Date 2022-08-22 13:29
*/
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
1.1.4编写配置文件
eureka会自己向自己注册一个服务,所以也需要指定eureka的地址信息,为了多个eureak之间—集群通信使用(注:编写配置文件defaultZone是没有提示的不用担心。)
server:
port: 10086 # 服务端口
spring:
application:
name: eurekaServer # eureka的服务名称
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://localhost:10086/eureka
1.1.5启动项目查看效果
点击图中idea上的链接,或者直接访问本地的端口
1.2服务注册
这里视频up主有demo,这里就不重复操作。直接新建一个springboot项目增加依赖等即可。
1.2.1引入客户端依赖
<!--eureka客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
1.2.2增加配置文件
spring:
application:
name: userService # eureka的服务名称
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://localhost:10086/eureka
配置完直接启动项目就可以看到效果了
如果想启动多个服务记住这个命令:-Dserver.port=8082
8082表示端口冲突了就换掉。
这里启动完出现两个实例
1.3服务发现
1.3.1服务名代替ip和端口
在本来的项目中是采用写死ip和端口的硬编码实现远程调用
接下来就采用服务名替换进行改进,实现服务名代替远程调用,无需关心ip和端口。
1.3.2添加负载均衡注解
在消费者的启动类,增加负载均衡注解——@LoadBalanced。
RestTemplate 只是简化http的调用方式,理解为一个http工具类,更好的调用RESTFul风格。
/**
* 创建RestTemplate并注入Spring容器
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
最终实现效果是:消费者类调用2次生产者时,我这里开了两个生产者,各调用了1次,实现了负载均衡,这里可以看到两次的参数不一样,表示2次调用。
2.负载均衡
2.1负载均衡原理
通过LoadBalancerInterceptor类里的intercept方法为入口切入逐步调试,这里简单介绍逻辑:
- 请求被LoadBalancerInterceptor(负载均衡器拦截器)拦截,得到服务名称http://userservice/1
- 交给RibbonLoadBalancerClient(功能区负载均衡器客户端)
- 交给DynamicServerListLoadBalancer(动态服务器列表负载均衡器)
- 去eureka拉取服务列表
- 根据列表去请求服务
2.2负载均衡策略
Ribbon内置了负载均衡规则类,以下进行简单介绍。
RoundRobinRule | 简单轮询列表,默认规则 |
---|---|
AvailabilityFilteringRule | 忽略以下两种服务器:(1)短路服务器。3次连接失败,被设置为短路 ,保持30s再失败持续时间几何级增加。(2)并发数过高的服务器。并发数可以由clientName.clientConfigNameSpace.ActiveConnectionsLimit属性进行配置 |
WeightedResponseTimeRule | 每个服务器根据响应时间获得权重值,响应时间越长权重越小。 利用权重值影响服务器的选择 |
ZoneAvoidanceRule | 按区域划分,然后对特定区域进行轮询 |
BestAvailableRule | 忽略短路服务器,并选择并发数较低的 |
RandomRule | 随机选择可用的 |
2.3调整负载均衡规则
2.3.1代码调整
作用域全局,在springboot启动文件加上注册一个Bean
@Bean
public IRule randomRule(){
return new RandomRule();
}
2.3.2配置文件调整
针对特定服务,在配置文件增加即可,userService表示服务名。
userService:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #负载均衡规则
2.4饥饿加载
Ribbon默认采用懒加载,在第一次访问时才会去创建LocalBalanceCilent,请求时间会比较长。
首次调用耗时较长,第二次就会比较快。
可以采用饥饿加载的方式改善这种情况,在服务一启动就自动加载,对配置文件进行配置。配置饥饿加载,重启服务会发现即使还没请求就直接完成了LocalBalance的加载和缓存。
ribbon:
eager-load:
enabled: true #开启饥饿加载
clients: #指定饥饿加载服务名称(列表形式,换行-)
- userService
请求时间和之前相比有所提升,还是比较慢的原因是因为还有很多服务也是第一次加载才初始化的比如DispatcherServlet
3.Nacos注册中心
nacos和eureka一样是个注册中心。只不过是由阿里巴巴开发的,现在也属于springCloud的一部分了。视频用的是1.4的版本,2.0版本也正式上线了,所以我打算使用最新版,踩踩坑。
下载地址:https://github.com/alibaba/nacos/releases/download/2.1.1/nacos-server-2.1.1.zip
3.1简单使用
3.1.1服务安装
下载完成后直接解压,目录很简单。
- bin:里面包含了各种脚本
- conf:配置文件
- target:里面就是jar包,nacos基于java实现的
然后就是准备启动,先看conf底下的application.properties,默认端口8848,没被占用就不用改。
启动命令,这里采用单机启动
#-m指定模式,standalone表示单机启动
startup.cmd -m standalone
表示启动成功,还多了三个文件
直接访问下,账号密码都是nacos,其实这个就是本机ip,nacos启动找的是第一块环回口网卡的ip,直接用这个地址也可以http://localhost:8848/nacos
3.1.2依赖配置
先在父工程增加依赖,再在子工程引入nacos依赖,记得把之前用到的eureka依赖注释掉。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- nacos客户端依赖包 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
3.1.3配置文件
对配置文件application进行更改,先注释掉eureka的配置,增加nacos配置,在spring底下。
server:
port: 8081
spring:
cloud:
nacos:
server-addr: localhost:8848
3.1.4验证使用
这里注册后发现nacos后台管理系统已经接收到三个服务,并且相互之间访问没有问题。
3.2分级存储模型
- 一级是服务
- 二级是集群,例如北京或上海
- 三级是实例,例如北京机房的某台部署了某服务的服务器
3.2.1模型介绍
一般的项目只跑一个,通过引入集群,部署多套系统,当某个系统意外宕机无法使用时,可以访问其他正常系统来保证系统的稳定运行,此为容灾。多个集群优先访问同区域的服务,跨域请求延迟过高。
3.2.2集群使用
配置yml
server:
port: 8081
spring:
application:
name: userService #服务名称
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: FZ #集群名称,FZ福州,XM厦门
这里我UserService1和UserService2集群名字采用FZ的配置先启动,UserService3改成XM后再启动,这里可以看到分别是不同的集群。
3.2.3集群负载均衡规则
实际中是希望,访问最近的服务,这里把OrderService配置到FZ集群后,还要修改负载均衡规则,实现优先本地集群访问。
userService:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #负载均衡规则优先
这里我测了很多次发现还是随机,最后发现之前启动类里的随机规则没有注释掉,并且NFLoadBalancerRuleClassName写错了,没有提示很容易错要细心点。访问多次XM集群的服务都没有收到,因为FZ集群存活,不会跨集群访问。
这里把FZ集群下线
orderservice实现一次跨集群访问。
PS:GrepConsole插件可以改变控制台的日志颜色(看着还挺爽,具体可以自己下载去使用下)
3.2.4加权负载均衡
通过权重可以设置服务器被访问的频率,权重为0表示完全不会被访问,权重值在0-1之间。
平滑升级:
1.进行一次版本迭代,把其中一台服务器权重调整为0直至没有用户存活。
2.再对这台权重为0 的服务器进行版本升级
3.修改权重为0.1放入少量的用户进来测试
3.2.5环境隔离
即使都注册在同一个注册中心,也可以通过命名空间的方式将他们进行隔离,让他们互相无法访问。环境隔离有以下好处:(待补充)
故障隔离:
故障恢复:
灰度测试:
3.2.5.1创建新的命名空间
3.2.5.2代码配置
namespace追加命名空间自动生成的id
cloud:
nacos:
server-addr: http://169.254.60.17:8848
discovery:
cluster-name: FZ
namespace: c0a15c25-e805-4c75-afef-de636ae276f7
3.2.5.3效果展示
由于环境隔离,所以orderservice无法访问public的服务
3.2.6Nacos和Eureka对比
3.2.6.相同点
Nacos有临时实例和非临时实例:
临时实例主动向服务端发送心跳,不跳了被剔除。
非临时实例是服务端问候是否或者,即使出问题也不会剔除,会等待恢复健康。
cloud:
nacos:
server-addr: http://169.254.60.17:8848
discovery:
ephemeral: false #是否是临时实例(默认true)
异常:在停掉临时实例,修改配置文件为非临时实例启动后报错,大概意思就是注册ip混乱了。
解决方法:等五分钟,再启动就能解决了。百度说删除protocol这个文件夹,重复操作依然存在,初步判定是nacos临时实例缓存清除需要时间。
3.2.6.2共同点
都支持服务注册和拉取
都支持心跳检测
Eureka都是客户端向服务端每隔30s定时拉取实例,但是如果30s内有实例宕机将会出现异常。
3.3配置管理
4.子标题
正文
在这里插入代码片
5.子标题
正文
在这里插入代码片