Spring Cloud Alibab
是一种微服务架构
1.介绍
1.1架构演变
单体架构-》垂直架构-》分布式架构-》SOA架构-》微服务架构
1.2微服务架构
把服务进行拆分细致,从而方便优化。和不会影响其他模块
治理:服务治理 注册中心【服务注册 发现 剔除】nacos
通讯:restful :feign
访问:网关 gateway
问题:容错
排错:链路追踪 skywalking
2.Spring Cloud Alibab介绍
微服务一站式解决方案
springcloud基础上实现
开源与平台服务分开维护
3.初步认识
1.分布式
一个模块创建多个子模块 通过RestTemplate调用远程接口
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restBuilder){
return restBuilder.build();
}
///
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/add")
public String add(){
System.out.println("下单成功");
String msg = restTemplate.getForObject("http://localhost:8002/stock/add", String.class);
//第一个参数接口,第二个返回类型
return "Hello World"+msg;
}
缺点:错中复杂难以维护 在springCloud中使用注册中心
环境搭建
因为Cloud版本管理,maven不能支持多个父亲使用dependencyManagement
加入pom
import
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2022.0.0.0-RC2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Alibaba微服务组件Nacos注册中心
1.认识
即注册中心+配置中心+服务管理
关键特性
服务发现+服务检测
动态配置服务
动态DNS服务
服务及其元数据管理
2.注册中心
管理所有微服务,解决服务器之间调用关系错综复杂,难以维护
核心功能:
1.服务注册:Nacos Client会通过发送Result请求项Nacos Server注册自己的服务并提供元数据 如ip 端口等 会存储在双层的内存Map中
2.服务心跳,定时心跳来持续通知 ,说明服务器可用,默认5s发送一次
3.服务器同步 集群时相互同步
4.服务发现 调用服务时候回发送请求给Nacos Server 获取列表并缓存到本地 定时
5.服务健康检查 超过15s 健康状态flase 超过30s 直接剔除
使用
1.官网中下载Nacos对应版本 2.x版本以上需要在conf目录下配置填tomcat的key网上找,在bin目录下启动startup.cmd。最好使用cmd启动.默认集群模式,右键编辑中改变模式。set MODE=“standalone” 设置为单机模式。
如果在服务器部署使用,PowerShell打开
2.添加依赖 在每个要使用的模块中添加
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
3.配置文件
server:
port: 8002
#应用名称
Spring:
application:
name: stockService #模块名字
cloud:
nacos:
server-addr: localhost:8848 #如果是服务器改为公网ip
discovery:
username: nacos
password:
namespace: public
注意:如果使用服务器搭建nacos 必须开端口+1000的端口 比如这里8848 需要开9848端口
使用 会自动解析stockService
String msg = restTemplate.getForObject("http://stockService/stock/reduct", String.class);
需要加上负载均衡器
@Bean
//添加负载均衡器
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder restBuilder){
return restBuilder.build();
}
可以创建相同类型不同的多个实例 不同端口
负载均衡器默认轮序机制 即一轮一轮来
默认netfix-ribbon负载均衡
3.nacos
命名空间:分离dev环境 开发环境等等
分组:更细致管理
雪崩保护:保护预值 数值0-1 比如0.5当 等于百分之50的实例挂掉 所有不可用. 用来以免所有请求到一个服务器 导致好的服务挂掉(不常用 一般降级)
永久实例:注册永久 就算挂掉也不会注销列表实例 心跳检测超过30s也存在
true是临时实例
ephemeral: false
元数据:对服务的一些选择 比如version =1的实力
权重:结合负载均衡器 设置越大 流量越大
4.常用配置
#应用名称
Spring:
application:
name: orderService
cloud:
nacos:
server-addr: http://47.109.76.214:8848
discovery:
username: nacos
password: hrzbtmbjwbjf
namespace: public
ephemeral: false #临时实例
group: DEFAULT_GROUP #指定分组
service: ${spring.application.name} #指定名称
weight: 1 #权重 1-100
access-key:
secret-key: #使用阿里AK&SK认证时需要配置
5.集群布置
需要nginx 负载均衡
参考链接https://blog.csdn.net/qq_51277752/article/details/125744997
注意如果出现Error creating bean with name ‘grpcSdkServer‘ 是端口被占用不止8849也还有9849 或者端口没开的原因。
在启动脚本编辑启动内存 电脑内存不够会报错
Ribbon(消费端)
只支持2022版本以下。2022版本Ribbon被移除
1.什么是Ribbon
目前主流的负载均衡方案:
1.比如Nginx 集中式负载均衡 在消费者和服务提供中间使用独立的代理方式负载
2.客户端根据自己请求情况负载均衡 Ribbon
Spring Cloud Ribbon基于Netflix实现客户端负载均衡,Ribbon客户端提供一系列的完善配置。通过Load Balancer获取到服务器提供的所有实例,基于某种规则(轮询,随机)去调用这写服务,也可以实现自己的算法
2.常见算法
随机 轮询 加权 加权轮询
地址哈希:通过客户端请求的Hash值来映射调度
最小链接数:哪个服务器压力最小
3.使用
在RestTemplate上使用@LoadBalanced注解
4.修改负载均衡策略
RandomRule(随机) RoundRobinRule(轮询)
RetryRule(轮询重试 在规定时间内来对不能用的实例重新获取)
WeightedResponseTimeRule(基于权重 对服务器响应时间越短 权重越大)
BestAvailableRule (过滤生效的服务器实例 然后顺便找出并发请求最小的)
ZoneAvoidanceRule(默认规则 复合判断区域性能和server可用性选择 .比如阿里云服务器在重庆 需要其他服务 选择近的成都服务器而不是北京)
导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
配置类
如果放在@compentScan能扫描的包下 会共享 从而不能单独对不同的服务者使用不同的规则
@Configuration
public class CloudRole {
//方法名一定叫iRule()
@Bean
public IRule iRule(){
return new RandomRule();
}
}
///
@SpringBootApplication
@RibbonClients(value = {
@RibbonClient(name ="stock-Service", configuration = CloudRole.class)
})
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
Ribbon组件被官方弃用,@LoadBalanced注解不生效的问题,添加loadbalance组件即可解决
2022版本
@Configuration
public class CloudRole {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
}
/
@SpringBootApplication
@LoadBalancerClient(value = "stock-Service", configuration = CloudRole.class)
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
配置文件
stock-Service:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
自定义 继承AbstractLoadBalancerRule
使用方法和上面2种相同
public class CustomRule extends AbstractLoadBalancerRule {
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
@Override
public Server choose(Object o) {
//获取当前请求的服务器实例
ILoadBalancer iLoadBalancer = this.getLoadBalancer();
List<Server> serverList = iLoadBalancer.getAllServers();
//获取随机的服务器实例
int random = ThreadLocalRandom.current().nextInt(serverList.size());
Server server = serverList.get(random);
//服务器实例是否可用
if (server.isAlive()){
return null;
}
return server;
}
}
推荐使用配置文件方式
开启启动时加载负载均衡器:
ribbon:
#叽饿加载 启动时候加载
eager-load:
enabled: true
#服务名称 逗号隔开
clients: stock-Service
同样2022版本不行 解决办法等待开发…
LoadBalancer (替换Ribbon)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
1.什么是LoadBalancer
是springcloud官方自己的负载均衡器 ,提供了2种客户端:
RestTemplate:
WebClient:是Spring WebFlux5.0版本提供的一个响应式编程进行HTTP客户端工具
2.目前2022版本策略
1.默认 RoundRobinLoadBalancer 轮巡
2.NacosLoadBalancer Nacos权重
Nacos中设置或者 配置文件中设置
配置类
public class CloudRole {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory,
NacosDiscoveryProperties nacosDiscoveryProperties) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new NacosLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name, nacosDiscoveryProperties);
}
}
方法二 优先级低
Spring:
application:
name: orderService
cloud:
loadbalancer:
nacos:
enabled: true
3.RandomLoadBalancer 随机
public class CloudRole {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
}
使用@LoadBalancerClient启动 方法和RibbonClients相同
注意同样不能被扫描到
Feign 客户端使用
处理优化服务和服务之间的调用
是Netflix开发式声明客户端(已经闭源),模板化HTTP客户端
官方OpenFeign增强 支持Springmvc的注解 整合了Ribbon和Nacos
使用:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1.创建接口 相识于mybatis
//name指定需要使用的服务名 path指定访问的路径 没有则不填
@FeignClient(name = "stock-Service",path = "/stock")
public interface StockFeignService {
//声明所需要调用的接口
@RequestMapping("/reduct")
public String reduct();
}
2.在启动类添加@EnableFeignClients注解
3.实现注入 直接获取方法
@Autowired
private StockFeignService stockFeignService;
@RequestMapping("/add")
public String add(){
System.out.println("下单成功");
//String msg = restTemplate.getForObject("http://stock-Service/stock/reduct", String.class);
String msg = stockFeignService.reduct();
return "Hello World"+msg;
}
配置:
日志配置:
Springboot默认级别info 不会显示debug 修改如下
logging:
level:
com.ry.order.feign: debug
四种级别
Full:记录响应请求的header body 元数据等等
NONE:不记录
BASIC:仅仅记录请求方法,URL,响应状态执行时间
HEADERS:记录在BASIC以上 记录请求和响应的header
全局配置
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
局部配置: 不加@Configuration 然和在需要调用的接口指定
@FeignClient(name = "stock-Service",path = "/stock",configuration = FeignConfig.class)
public interface StockFeignService {
//声明所需要调用的接口
@RequestMapping("/reduct")
public String reduct();
}
配置文件
openfeign:
client:
config:
##指定服务名
stock-Service:
##日志级别
logger-level: basic
契约配置:
还原为Feign原生注解 只能使用@RequstLine等等注解
@Bean
public Contract feignContract(){
return new Contract.Default();
}
openfeign:
client:
config:
##指定服务名
stock-Service:
##日志级别
logger-level: basic
contract: feign.Contract.Default
超时配置:
openfeign:
client:
config:
##指定服务名
stock-Service:
##日志级别
logger-level: basic
contract: feign.Contract.Default
#连接超时时间 默认2s
connect-timeout: 5000
#读取超时时间 默认5s
read-timeout: 6000
@Bean
public Request.Options feignContract(){
return new Request.Options(50000, 60000);
}
拦截器
1.创建拦截器 实现RequestInterceptor
public class FeignInterceptorMy implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
//进行拦截操作
}
}
2.配置类中实现
@Bean
public RequestInterceptor feignAuthInterceptor(){
return new FeignInterceptorMy();
}
3.配置文件实现
是一个集合形式
openfeign:
client:
config:
##指定服务名
stock-Service:
##日志级别
logger-level: basic
contract: feign.Contract.Default
#连接超时时间 默认2s
connect-timeout: 5000
#读取超时时间 默认5s
read-timeout: 6000
request-interceptors:
- com.ry.order.Interceptor.feign.FeignInterceptorMy
RequestTemplate requestTemplate) {
//进行拦截操作
}
}
2.配置类中实现
```java
@Bean
public RequestInterceptor feignAuthInterceptor(){
return new FeignInterceptorMy();
}
3.配置文件实现
是一个集合形式
openfeign:
client:
config:
##指定服务名
stock-Service:
##日志级别
logger-level: basic
contract: feign.Contract.Default
#连接超时时间 默认2s
connect-timeout: 5000
#读取超时时间 默认5s
read-timeout: 6000
request-interceptors:
- com.ry.order.Interceptor.feign.FeignInterceptorMy