微服务架构
微服务主旨是将一个原本独立的系统拆分成多个小型服务,并且每个服务都能独立运行。 因为每个服务可以独立运行,所以都有属于自己的数据库。
SpringCloud
SpringCloud是一系列框架的有序集合,基于SpringBoog开发,需要版本对应。
Eureka
Eureka包含两个组件:EurekaServer(注册中心) 和 EurekaClient(服务提供者、服务消费者)
基础使用:
1. 搭建Eureka-Server服务模块
- 引入SpringCloud和eureka-server依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--eureka server依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
- 创建配置文件Application.yml
server:
port: 8761 #默认端口
#eureka 配置
eureka:
instance:
hostname: localhost #主机名
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka #eureka服务端地址
register-with-eureka: false #是否将自己的路径注册到eureka上
fetch-registry: false #是否要从eureka中抓取路径
- 创建启动类,在启动类上添加注解@EnableEurekaServer启动模块
@SpringBootApplication
//启用EurekaServer
@EnableEurekaServer
public class EurekaApp {
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class,args);
}
}
2. 创建Provider和Consumer模块
- 引入eureka-client依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 在启动类上添加@EnableEurekaClient注解,表示是客户端。(可省略)
- 配置文件中添加Eureka相关配置,name配置是注册到eureka上的应用名称
server:
port: 9000
eureka:
instance:
hostname: localhost #主机名
client:
service-url:
defaultZone: http://eureka-server1:8761/eureka #eureka服务端地址
spring:
application:
name: eureka-consumer #设置当前应用的名称,会在eureka中显示。将来需要使用该名称获取路径
3. Consumer服务从eureka中抓取Provider地址完成远程调用
- 在要抓取地址的类中注入DiscoveryClient对象,调用其方法获得host和port,拼接成url
@Autowired
private DiscoveryClient discoveryClient;
//从eureka中获取provider数据
//名称是Provider服务注册到Eureka上的应用名称
List<ServiceInstance> instances = discoveryClient.getInstances("EUREKA-PROVIDER");
ServiceInstance instance = instances.get(0);
String host = instance.getHost();//获取ip
int port = instance.getPort();//获取端口
String url = "http://"+host+":"+port+"/goods/findOne/"+id;
restTemplate.getForObject(url, Goods.class);
Eureka自我保护机制
如果Eureka在15分钟内未收到超过85%客户端节点的正常心跳,则开启自动保护。保护期间不剔除任何一个服务,但可接收新服务的注册,等到网络稳定时将新服务同步到其他服务中。
Eureka中默认开启自我保护机制,可通过配置文件将其关闭
eureka:
server:
enable-self-preservation: false #关闭自我保护机制
Eureka高可用
Eureka将自己作为服务注册到其他的Eureka上,进行相互注册。实现客户端数据的共享,避免单个Eureka异常导致整体无法运行。
Ribbon客户端负载均衡
Ribbon是基于Http和TCP的客户端负载均衡工具。
功能:
- 简化远程调用
- 负载均衡
简化远程调用
- 在RestTemplate的Bean注解上添加@LoadBalance注解
@Configuration
public class RestTemplateConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
- 编写provider的url地址时直接使用Eureka中的应用名代替host:port处
String url = "http://FEIGN-PROVIDER/***";
负载均衡
客户端对于服务端集群调用规则
负载均衡策略:
- 随机
- 轮询
- 最小并发
- 过滤
- 响应时间
- 轮询重试
- 性能可用性 设置负载均衡策略:
- 创建一个类作为负载均衡规则类。定义一个方法,返回值类型为IRule,方法内部直接返回上述负载均衡类型的对象。
- 在配置类中添加配置
user-service: #生产者服务名称
ribbon:
NFloadBalancerRuleClassName:XXX #负载均衡类型
- 启动类上添加注解@RibbonClient(name="应用名称",configuration=自己创建的负载均衡规则类.class)
Feign声明式服务调用
- Feign的时一个声明式的web service客户端,便于客户端的设置。
使用方法
- Consumer客户端导入依赖
<!--feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- Consumer启动类上添加注解@EnableFeignClients,开启Feign的功能
- 创建Feign的声明接口。在接口类上添加注解@FeignClient,设置Value属性,值为Provider服务提供者的应用名称。接口方法的声明规则和服务提供方接口保持一致
@FeignClient(value = "FEIGN-PROVIDER")
public interface GoodsFeignClient {
@GetMapping("/goods/findOne/{id}")//自动会拼接为FEIGN-PROVIDER/goods/findOne/{id}
public Goods findGoodsById(@PathVariable("id") int id);
}
- 调用Provider时直接注入Feign接口方法,调用其中方法。
超时设置
日志记录
Hystrix熔断器
- Hystrix用于隔离访问远程服务、第三方库,防止出现级联失败(雪崩)。
- Hystrix主要功能:
- 隔离
- 降级
- 熔断
- 限流 隔离
- 线程池隔离:给每个服务划分一个线程池
- 信号量隔离:给每个服务限制最多多少线程访问 降级
- 异常:当服务产生异常时,调用服务的降级方案,返回一个默认值
- 超时:当网络产生问题,连接超时时,客户端调用对该服务连接超时的降级方案
熔断
当在某段时间内服务返回的异常超过其阈值,则产生熔断机制,停止对此服务的任何调用。熔断机制时间过去后,根据此服务运行是否还产生异常来判断是否恢复调用
服务提供方降级
- 在服务提供方引入依赖
<!-- hystrix --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>- 定义降级方法
- 方法返回值和原方法一致
- 方法的参数值和原方法一致
public Goods findOne_fallback(int id){ Goods goods = new Goods(); goods.setTitle("降级了~~~"); return goods; } - 在需要有降级方法上添加@HystrixCommand注解配置降级方法,属性fallbackMethod值为定义的降级方法名
@GetMapping("/findOne/{id}") @HystrixCommand(fallbackMethod = "findOne_fallback")- 启动类上添加@EnableCiruitBreaker注解开启Hystrix功能
服务消费方降级
- 定义feign调用接口实现类,复写方法,即为降级方法
- 添加配置,开启hystrix服务
# 开启feign对hystrix的支持 feign: hystrix: enabled: true- feign接口类上添加注解@FeignClient,属性Value指定对哪个服务降级,fallback指定降级类
@FeignClient(value = "HYSTRIX-PROVIDER",fallback = GoodsFeignClientFallback.class)
网关
- 网关为微服务架构提供一种简单而有效的统一的API路由管理方式 使用方法
- 搭建网关模块,在网关模块中引入starter-gateway依赖。因为需要和eureka进行交互,所以得导入eureka依赖
<!--引入gateway 网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 配置文件
- 将自己注册到Eureka中
eureka: client: service-url: defaultZone: http://localhost:8761/eureka- 路由配置
cloud: # 网关配置 gateway: # 路由配置:转发规则 routes: #集合。 - id: gateway-provider # 动态路由,使用 uri:lb://应用名称 代替静态路径 uri: lb://GATEWAY-PROVIDER # uri: 转发路径 predicates: # predicates: 条件,用于请求网关路径的匹配规则 - Path=/goods/** - id: gateway-consumer # uri: http://localhost:9000 uri: lb://GATEWAY-CONSUMER predicates: - Path=/order/**
Gateway全局过滤器
- 系统初始化时加载,作用在每一个路由上
- 步骤:
- 定义类实现GlobalFilter和Ordered接口
@Component public class MyFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("自定义全局过滤器执行"); return chain.filter(exchange);//放行 } /** * 过滤器排序 * @return 数值越小 越先执行 */ @Override public int getOrder() { return 0; } }
Config分布式配置中心
- 用于管理分布式场景下的多配置文件管理和维护。配置信息改变时不需要重启即可更新配置信息到服务
基础操作
- 创建远程仓库。用的Gitee
- 搭建ConfigServer模块,导入Config-server依赖
<!-- config-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
- 编写启动类,添加@EnableConfigServer,启动configServer功能
- 编写配置文件,将自己注册到eureka中
# spring cloud config
cloud:
config:
server:
# git 的 远程仓库地址
git:
uri: ***
label: master # 分支配置
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
- 在Provider和Consumer服务中导入starter-config依赖
<!--config client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
- 创建bootstrap.yml,配置Config server地址,读取远程配置文件
# 配置config-server地址
# 配置获得配置文件的名称等信息
spring:
cloud:
config:
# 配置config-server地址
uri: http://localhost:9527
# 配置获得配置文件的名称等信息
name: config # 文件名
profile: dev # profile指定,config-dev.yml
label: master # 分支
# uri+name+profile+label自动组合为 http://localhost:9527/master/config-dev.ymml
#从配置中心去寻找config-server地址
discovery:
enable: true #是否从eureka中查找
service-id: config-server #eureka中应用名称
- 获取远程配置文件时,使用@Value注入即可
@Value("${SpringCloud}")
private String SpringCloud;
Bus消息总线
- 使用消息中间件将分布式的节点连接起来。用于广播配置文件的更改。
- 消息中间件可使用RibbitMQ和Kafka
基础使用
- 在provider和consumer中引入bus依赖:bus-amqp
<!-- bus -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 在provider和consumer中的bootstrap配置RabbitMQ
spring:
#配置rabbitmq信息
rabbitmq:
host: localhost
port: 5672
virtual-host: /
- 在config-server中的bootstrap设置暴露监控断点:bus-refresh
management:
endpoints:
web:
exposure:
include: '*'