微服务其实就是将一个大的架构进行模块化的拆分,每个模块就是一个微服务,各个微服务组合成一个整体:
实现微服务管理的方式:
Dubbo:
SpringCloud:
dubbo和SpringCloud对比:
dubbo只是实现类微服务的治理,但是springCloud实现微服务架构下的诸多组件
dubbo使用的是RPC通讯协议,SpringCloud采用的是RESTful完成通讯,由于SpringCloud实现的组件比较的多,所以SpringCloud的效率低于dubbo
生产端:
@RestController
public class StudentController {
@GetMapping("/find/{age}")
public Student find(@PathVariable int age) {
return new Student("张三", age);
}
}
消费端:
@RestController
@RequestMapping("/consumer")
public class ComtstumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("{age}")
public Student find(@PathVariable int age) {
System.out.println(age);
//知道访问的接口,然后完成拼串
String url="http://localhost:8080/find/"+age;
return restTemplate.getForObject(url, Student.class) ;
}
}
RestTemplate引入:
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
SpringBoot环境下,依赖引入web的即可
RestTemplate远程调用是Spring进行封装的,但是跨域问题,底层已经解决!关于Resttemplate的api查看源码即可!
Eureka的架构图(看图秒懂,其实其他的注册中心大同小异):
关于Eureka的相关介绍,.......无关紧要的,废话就算啦:
其实烦的就是这些配置...所以我才在做模板,方便日后使用粘贴修改
eureka: server: enable-self-preservation: false #是否开启自我保护机制,默认true即使服务有问题,也会保存(防止网络抖动等), eviction-interval-timer-in-ms: 50000 #清理死服务时间间隔,默认是60000 dashboard: enabled: true #是否启用service的web控制台 path: / #设置web控制台的访问路径eureka: instance: hostname: localhost #主机名字 prefer-ip-address: true #否将自己的ip注册Eureka上,默认是不注册ip,注册的是主机名 ip-address: #设置当前实例的ip instance-id: #修改instance显示的id lease-renewal-interval-in-seconds: 20 #Eureka客户端向服务端发送心跳的时间间隔 lease-expiration-duration-in-seconds: 100 #超过该时间没有收到心跳,剔除服务 client: service-url: defaultZone: #Eureka的service地址 register-with-eureka: true #是否将自己的路径注册到eurea上 fetch-registry: true # 是否从eureka上抓取数据
使用Eureka做为注册中心(这块注册中心使用集群实现高可用):
创建父项目使用maven进行统一的依赖管理(可以分开,看习惯):
parent中pom.xml
org.springframework.boot spring-boot-starter-parent 2.1.0.RELEASE UTF-8 UTF-8 1.8 UTF-8 Greenwich.RELEASE org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import
pom依赖:
org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-server
service1配置:
#直接访问该端口就是Eureka的web控制台 server: port: 8762 eureka: instance: hostname: nanfeng # 主机名 client: service-url: # 将本机服务注册到其他集群节点,这块设置的是两个节点,所以需要将本机的服务注册到另外一个服务上, # 若是单节点,这块就可以不配置了 # 下面这块改成需要注册的主机名,注意并不是本地主机名,是目标主机名名,在开发阶段采用端口识别,但是在上线后采用ip识别(端口号可以修改) defaultZone: http://localhost:8761/eureka register-with-eureka: true # 是否将自己的路径 注册到eureka上。eureka server 单节点不需要的,集群需要,eureka provider client 需要 fetch-registry: true # 是否需要从eureka中抓取路径。eureka server单节点不需要,集群需要 ,eureka consumer client 需要 server: enable-self-preservation: true # 是否开启自我保护机制(开启后即使注册到客户端的服务出现问题,也不会被清除,在开发测试不开启,上线后开启) eviction-interval-timer-in-ms: 3000 # 检查服务的时间间隔 spring: application: name: server #这个名字必须相同,同一个节点
service2
server: port: 8761 eureka: instance: hostname: localhost # 主机名 client: service-url: # 将本机服务注册到其他集群节点,这块设置的是两个节点,所以需要将本机的服务注册到另外一个服务上, # 若是单节点,这块就可以不配置了 # 下面这块改成需要注册的主机名,注意并不是本地主机名,是目标主机名名,在开发阶段采用端口识别,但是在上线后采用ip识别(端口号可以修改) defaultZone: http://nanfeng:8762/eureka register-with-eureka: true # 是否将自己的路径 注册到eureka上。eureka server 单节点不需要的,集群需要,eureka provider client 需要 fetch-registry: true # 是否需要从eureka中抓取路径。eureka server单节点不需要,集群需要 ,eureka consumer client 需要 server: enable-self-preservation: true # 是否开启自我保护机制(开启后即使注册到客户端的服务出现问题,也不会被清除,在开发测试不开启,上线后开启) eviction-interval-timer-in-ms: 3000 # 检查服务的时间间隔 spring: application: name: server #节点名字保证相同
service启动类添加注解@EnableEurekaServer,标注是一个Eureka的service服务:
@SpringBootApplication
@EnableEurekaServer
public class EurekaServiceApp {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceApp.class, args);
}
}
注意:在搭建集群的时候启动两个服务相互注册的时候会报错,当两个服务都启动了,这个错误就不存在了!
org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client
生产端:
配置文件:
# 本地主机的启动端口号 server: port: 8002 # eureka客户端服务的标准配置 eureka: instance: hostname: localhost # 主机名 prefer-ip-address: true # 将当前实例的ip注册到eureka server 中。默认是false 注册主机名 ip-address: 127.0.0.1 # 设置当前实例的ip # 设置web控制台显示的 实例id,就是在注册中心显示的示实例的信息 instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port} lease-renewal-interval-in-seconds: 3 # 每隔3 秒发一次心跳包,服务续约 # 如果9秒没有发心跳包,服务器呀,你把我干掉吧,一般上线的服务都会在服务端开启自我服务的保护, #即使自己的服务出现问题,也不会将自己的服务杀掉,(可能指网络抖动,等文体,随后服务会回恢复正常) lease-expiration-duration-in-seconds: 9 client: service-url: # eureka服务端地址,将来客户端使用该地址和eureka进行通信 defaultZone: http://localhost:8761/eureka,http://nanfeng:8762/eureka spring: application: name: provider # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径
controller:
@RestController
public class StudentController {
@GetMapping("/find/{age}")
public Student find(@PathVariable int age) {
return new Student("张三", age);
}
}
启动类添加注解@EnableEurekaClient(生产端和消费端的启动类相同,就是添加注解):
@SpringBootApplication
@EnableEurekaClient
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class,args);
}
}
消费端:
消费端配置文件:
# 本地主机的启动端口 server: port: 8001 # eruake客户端消费的配置 eureka: instance: hostname: nanfeng # 主机名 client: service-url: # eureka服务端地址,将来客户端使用该地址和eureka进行通信,这块需要将服务自己的信息注册到集群环境中(下面的主机名在使用时修改即可), defaultZone: http://localhost:8761/eureka,http://nanfeng:8762/eureka spring: application: # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径, # 若是不设置会在eureka的控制台上无法显示信息 name: consumer
RestTemplate配置类(这块使用了ribbon的注解@LoadBalanced 简化开发,ribbon和Eureka是同一家产品,Eureka中集成有ribbon,关于ribbon使用:Ribbon实现客户端负载均衡_楠~枫的博客-CSDN博客):
@Configuration
public class RestTemplateConfig {
/*
* 注入远程调用
* */
@LoadBalanced //ribbon注解:添加这个注解以后可以通过服务名字掉进行地址的绑定
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
controller(代码含有注释,参考):
@RestController
@RequestMapping("/consumer")
public class ComtstumerController {
@Autowired
private RestTemplate restTemplate;
//使用注册中心后
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("{age}")
public Student find(@PathVariable int age) {
//知道访问的接口,然后完成拼串
String url = "http://localhost:8080/find/" + age;
return restTemplate.getForObject(url, Student.class);
}
@GetMapping("discover/{age}")
public Student findDiscovery(@PathVariable int age) {
//通过discovery获取服务对象
List instances = discoveryClient.getInstances("provider");
//判断集合是否有数据
if (instances == null || instances.size() == 0) {
//集合没有数据
return null;
}
ServiceInstance instance = instances.get(0);
String host = instance.getHost();//获取ip
int port = instance.getPort();//获取端口
//知道访问的接口,然后完成拼串
String url = "http://"+host+":"+port+"/find/" + age;
return restTemplate.getForObject(url, Student.class);
}
/*
*使用aribbon后的简化调用,使用ribbon上面find2就不能使用原来的方式访问了,要痛过服务提供方的名称访问
* */
@GetMapping("ribbon/{age}")
public Student findDiscoveryRibbon(@PathVariable int age) {
String url = "http://provider/find/" + age;
return restTemplate.getForObject(url, Student.class);
}
}
关于Eureka的基本使用完结!配置文件超级烦,参考修改,为了偷懒,,,,,,,,,,,,,啦啦啦啦啦啦
Consul是go语言写的,是个软件包:
官网地址:https://www.consul.io
度盘:https://pan.baidu.com/s/1tRvNmrG7-olM7UXjNiPoeg
提取码:0vm6
废话不多说,直接用:
下载下来直接解压即可:
启动(解压目录下):
.\consul.exe agent -dev # 开发形式启动,dev开发模式启动,不会持久化数据
访问控制台:localhost:8500
实例(基本上代码层面没啥改变,就是配置文件的形式):
父项目pom同Eureka实例:
pom依赖生产端和消费端相同
org.springframework.cloud spring-cloud-starter-consul-discovery org.springframework.boot spring-boot-starter-web
消费端配置:
server: port: 8001 spring: cloud: consul: # 将服务的信息注册到端口 host: localhost # consul 服务端的 ip port: 8500 # consul 服务端的端口 默认8500.consul的默认启动端口号 discovery: service-name: ${spring.application.name} # 当前应用注册到consul的名称 prefer-ip-address: true # 注册ip application: name: consumer # 应用名称
生产端配置文件:
# 常规服务启动的端口 server: port: 8002 spring: cloud: consul: # 将自己的信息注册到指定的地址 host: localhost # consul 服务端的 ip port: 8500 # consul 服务端的端口 默认8500 discovery: service-name: ${spring.application.name} # 当前应用注册到consul的名称 prefer-ip-address: true # 注册ip application: name: provider # 应用名称
其实这两个配置没为神马区别:
消费端启动类:
@SpringBootApplication
@EnableDiscoveryClient//开启dis...
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
}
消费端RestTemplate引入:
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
消费端Controller:
@RestController
@RequestMapping("/consumer")
public class ComtstumerController {
@Autowired
private RestTemplate restTemplate;
//使用注册中心后
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("{age}")
public Student find(@PathVariable int age) {
//知道访问的接口,然后完成拼串
String url = "http://localhost:8080/find/" + age;
return restTemplate.getForObject(url, Student.class);
}
@GetMapping("discover/{age}")
public Student findDiscovery(@PathVariable int age) {
//通过discovery获取服务对象
List instances = discoveryClient.getInstances("provider");
//判断集合是否有数据
if (instances == null || instances.size() == 0) {
//集合没有数据
return null;
}
ServiceInstance instance = instances.get(0);
String host = instance.getHost();//获取ip
int port = instance.getPort();//获取端口
//知道访问的接口,然后完成拼串
String url = "http://"+host+":"+port+"/find/" + age;
return restTemplate.getForObject(url, Student.class);
}
}
其他的省略,主要是配置文件!!!关于Consul基础使用就这啦,主要是配置文件
nacos是阿里巴巴的产物,是一个软件包:下载地址:https://github.com/alibaba/nacos/releases
度盘链接:https://pan.baidu.com/s/1_ZvotToFjgn0sHhYr92mow
提取码:3ik4
啦啦啦啦啦,```````````````````````````````~~~~~~~~~~~~~~~~~~,直接使用吧!
解压后:
bin目录下的staetup.cmd双击启动
默认端口:8848
控制台:localhost:8848/nacos/#/login
控制台的账号:nacos
密码:nacos
linux和window相同,只是启动文件变成sh
启动完事
其实还是学配置文件,真的是很烦这些配置文件
实例:
父项目依赖同Eureka实例
依赖(生产消费相同):
org.springframework.cloud spring-cloud-starter-alibaba-nacos-discovery 0.2.2.RELEASE com.alibaba.nacos nacos-client 1.1.0 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator
配置文件生产消费两边相同(修改即可):
server: port: 8002 spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 # 配置nacos 服务端地址 8848默认端口号 application: name: provider # 服务名称
代码和Consul相同,同样的代码粘贴,,,,,
关于Nacos就这样吧
明天吧...............................
续上地址:Dubbo_楠~枫的博客-CSDN博客
概述:
Feign是一种http客户端(主要用于消费端),用来实现http远程调用的,可以实现远程端调用像在本地方法一样,和Eureka是一家产品,在feign基层封装了ribbon和restful风格请求
实现原理:
接口加注解的形式
Feign的日志级别为Debug,只识别Debug级别的日志
Feign超时设置(Feign的超时机制是建立在ribbon的基础上的),其实就是设置ribbon的超时机制,设置服务响应和处理的时间限制!若是服务端节点出现问题会雪崩!
雪崩:
所谓雪崩就是服务全部瘫痪,根本原因是某个服务调用过程中,由于服务端出现问题,调用端不断的调用,线程积压,最终瘫痪形成的链式反应:图示:
案例示例(基于上面搭建的Eureka做改进的):
消费端:
消费端添加feign的pom依赖:
org.springframework.cloud spring-cloud-starter-openfeign
消费端配制文件(超时配置,日志配置)
# 本地主机的启动端口 server: port: 8001 # eruake客户端消费的配置 eureka: instance: hostname: nanfeng # 主机名 client: service-url: # eureka服务端地址,将来客户端使用该地址和eureka进行通信,这块需要将服务自己的信息注册到集群环境中(下面的主机名在使用时修改即可), defaultZone: http://localhost:8761/eureka,http://nanfeng:8762/eureka spring: application: # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径, # 若是不设置会在eureka的控制台上无法显示信息 name: consumer # 设置当前的日志级别 debug,feign只支持记录debug级别的日志 logging: level: com.itheima: debug # 设置Feign的超时时间,但是Feign的底层实际是Ribbon # 设置Ribbon的超时时间, ribbon: ConnectTimeout: 1000 # 连接超时时间 默认1s ReadTimeout: 3000 # 逻辑处理的超时时间 默认1s
消费端Feign的接口(代码写法在注释中)
/**
* feign的接口其实就是将RestTemplat的bean加载进来,将原来的请求地址:String url = "http://provider/find/" + age;进行了封装
*/
/*
* @FeignClient完成服务主机地址和名字以及端口的封装,SpringCloud对feign进行了封装,SpringMVC支持识别feign注解
**/
@FeignClient(value = "provider",configuration = FeignLogConfig .class)
public interface MyFeign {
/*
* @GetMapping保持和服务提供方的路径同即可
*/
@GetMapping("/find/{age}")
Student find(@PathVariable int age);
}
MyResttemplateConfig其实就是一个引入RestTemplate的配置类(这个在这可以不要,但是在controller中之前的案例还在,所以这块保存,否则之前的案例报错看不到对比)
/**
* 其实就是一个RestTemplate的配置类
*/
@Configuration
public class MyResttemplateConfig {
/*
ribbon的注解,其实在这块有没有都可以,会自动识别的
*/
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
FeignLogConfig 日志配置类:
@Configuration
public class FeignLogConfig {
/*
NONE,不记录
BASIC,记录基本的请求行,响应状态码数据
HEADERS,记录基本的请求行,响应状态码数据,记录响应头信息
FULL;记录完成的请求 响应数据
*/
@Bean
public Logger.Level level(){
return Logger.Level.FULL;
}
}
controller类
@RestController
@RequestMapping("/consumer")
public class ComtstumerController {
@Autowired
private RestTemplate restTemplate;
//使用注册中心后
@Autowired
private DiscoveryClient discoveryClient;
/**
* 注入feign
*/
@Autowired
private MyFeign myFeign;
@GetMapping("{age}")
public Student find(@PathVariable int age) {
//知道访问的接口,然后完成拼串
String url = "http://localhost:8080/find/" + age;
return restTemplate.getForObject(url, Student.class);
}
@GetMapping("discover/{age}")
public Student findDiscovery(@PathVariable int age) {
//通过discovery获取服务对象
List instances = discoveryClient.getInstances("provider");
//判断集合是否有数据
if (instances == null || instances.size() == 0) {
//集合没有数据
return null;
}
ServiceInstance instance = instances.get(0);
String host = instance.getHost();//获取ip
int port = instance.getPort();//获取端口
//知道访问的接口,然后完成拼串
String url = "http://"+host+":"+port+"/find/" + age;
return restTemplate.getForObject(url, Student.class);
}
/*
*使用aribbon后的简化调用,使用ribbon上面find2就不能使用原来的方式访问了,要痛过服务提供方的名称访问
* */
@GetMapping("ribbon/{age}")
public Student findDiscoveryRibbon(@PathVariable int age) {
String url = "http://provider/find/" + age;
return restTemplate.getForObject(url, Student.class);
}
/**
* 通过Feigen接口调用
*/
@GetMapping("feign/{age}")
public Student findFeign(@PathVariable int age) {
return myFeign.find(age);
}
}
启动类开启Feign支持:
/**
* 新版本部分SpringCloud组件的注解默认已经开启
*/
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient//开启dis支持...
/**
* 开启feign的支持
*/
@EnableFeignClients
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
}
生产端和注册中心基于上面Eureka原来案例不变化,关于Feign声明式服务调用就这样了!!!!!!~~~使用参考修改即可!
概述:Hystix ,Eureka,Feign,Robbon都是一家的,Hystix是开源的一个延迟和容错库,防止出现雪崩的.......反正就是很溜!
隔离:信号量隔离/线程池隔离
信号量隔离,其实就是某个节点发来请求统计次数,在某个时间端内达到多少次限制请求,过一段时间然后缓慢释放一部分请求,若是没有问在逐渐放行请求
线程池隔离:设置线程数量,有空闲线程放行新的请求(实际使用的也是这个)
服务降级:针对某个服务出现异常/超时
下面案例编码实现
熔断:这个实现原理在隔离中已经说了,两个关系很密切,隔离的条件达到后就会熔断,其实就是阻止请求
限流:就是熔断后缓慢放行请求的过程,根据限号量.空闲线程量
隔离,熔断,限流,只是Hystix不同时期的状态而已,三个组成hystix的工作过程!服务降级是对异常或者熔断的一种处理!
概念说明白了,案例实现:
案例(基于Feign案例添加和改动):
生产端:需要做的就是引入hystix依赖,编写降级方法,设置降级参数,启动类开启Hystixz支持
生产段pom依赖(生产端不需要):
org.springframework.cloud spring-cloud-starter-netflix-hystrix
生产端配置文件(基于Feign的配置文件无需修改/没有提及的都是基于之前案例的代码或者文件):
生产端代码(配置hystix降级注解的参数,写降级方法):
@RestController
public class StudentController {
/**
* @HystrixCommand设置服务降级的一些参数,注解参数解析: fallbackMethod:字符串类型参数,参数是同类的降级方法的方法名
* commandProperties:设置一些降级参数信息,数组
*/
@HystrixCommand(fallbackMethod = "findDomate", commandProperties = {
//设置Hystrix的超时时间,默认1s
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
//监控时间 默认5000 毫秒
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),
//失败次数。默认5000毫秒内失败20次,开启熔断器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),
//失败率 默认50%,也会开启熔断器
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")
})
@GetMapping("/find/{age}")
public Student find(@PathVariable int age) throws InterruptedException {
Thread.sleep(5000);
return new Student("张三", age);
}
/**
* 降级方法的写法:
* 1 和原来的方法参数相同
* 2 和原来方法的返回值相同
*/
public Student findDomate(int age) {
return new Student("生产端降级了", 0);
}
}
启动类开启hystix支持:
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix//开启Hystix支持
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class,args);
}
}
消费端
消费端pom依赖基于feign不变:
消费端配置文件:
# 本地主机的启动端口 server: port: 8001 # eruake客户端消费的配置 eureka: instance: hostname: nanfeng # 主机名 client: service-url: # eureka服务端地址,将来客户端使用该地址和eureka进行通信,这块需要将服务自己的信息注册到集群环境中(下面的主机名在使用时修改即可), defaultZone: http://localhost:8761/eureka,http://nanfeng:8762/eureka spring: application: # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径, # 若是不设置会在eureka的控制台上无法显示信息 name: consumer # 设置当前的日志级别 debug,feign只支持记录debug级别的日志 logging: level: com.itheima: debug # 设置Feign的超时时间,但是Feign的底层实际是Ribbon # 设置Ribbon的超时时间,超时会降级 ribbon: ConnectTimeout: 1000 # 连接超时时间 默认1s ReadTimeout: 3000 # 逻辑处理的超时时间 默认1s #注意:在生产端也可以设置降级,但是设置的生产端的超时设置大于消费端的超时, #会执行生产端的超时,消费端满足降级会先执行消费端降级 #开启Hystix支持 feign: hystrix: enabled: true
Feign接口(配置降级方法):
/**
* feign的接口其实就是将RestTemplat的bean加载进来,将原来的请求地址:String url = "http://provider/find/" + age;进行了封装
*/
/*
* @FeignClient完成服务主机地址和名字以及端口的封装,设置降级的实现类!SpringCloud对feign进行了封装,SpringMVC支持识别feign注解
**/
@FeignClient(value = "provider",configuration = FeignLogConfig.class,fallback = Demote.class)
public interface MyFeign {
/*
* @GetMapping保持和服务提供方的路径同即可
*/
@GetMapping("/find/{age}")
Student find(@PathVariable int age);
}
Feign接口实现类中写降级方法:
/**
* feign的降级实现:
* 定义类实现feign接口
* 将实现类加入到ioc中
*/
@Component//需要ioc识别这个bean
public class Demote implements MyFeign {
@Override
public Student find(int age) {
return new Student("消费端降级",0);
}
}
启动类基于feign案例:
基本上代码实现就到这了,该有的解释代码中已经做了说明,参考修改即可!
关于熔断器的工作机制:在解释hystix隔离时已经说明白了,这块在说一下:
达到隔离条件,进行熔断,过一段时间进行部分放行(即限流),若是放行的请求依然有问题,继续熔断,若是没有问题,全部放行,依次循环!
熔断器监控:啦啦啦,是有这个东西,但是应该是运维人员搞的,和我应该没多大关系!
概述:Gateway其实就是为诸多分布式服务提供统一的 Api管理,解决前端访问各个服务时路径的不同和身份验证等诸多问题!
理解图:
能完成这个功能的还有:Nginx+ Lua.这个我目前还不是很熟悉,回头学习一下,再做整理!
理论都简单,烦人的还是配置文件:
静态路由:配置文件中写死
动态路由:将自己注册到注册中心,然后从注册中心获取uri
服务名称配置: 访问路径必须携带服务的名称:大写名称/小写名称
过滤器:主要是在请求的前后做一些操作
过滤器方式:
pre :前置操作:在转发之前执行,可以做参数校验、权限校验、流量监控、日志输出、协议转换
post 后置操作:在响应之前执行,可以做响应内容、响应头的修改,日志的输出,流量监控等
局部过滤器GatewayFilter: 针对单个路由
全局过滤器GlobalFilter :针对所有路由
全局路由主要处理的实现有(这些实现百度有):
以上配置全部在下面的案例中体现,参考修改即可:
案例(基于Hystix案例进行修改添加,从头搭建环境太繁琐):
在parent下新建网关模块:
模块依赖:
org.springframework.cloud spring-cloud-starter-gateway org.springframework.cloud spring-cloud-starter-netflix-eureka-client
Getway的配置:
server: port: 80 spring: application: name: Gateway_API cloud: # 网关配置 gateway: # 路由配置:转发规则 routes: # 参数是一个集合。 # id: 唯一标识。默认是一个UUID,一般设置为节点服务的name # uri: 转发服务提供者的访问路径 # predicates: 条件集合,用于请求网关路径的匹配规则,就是该路径下的某个处理器(具体到某个方法) # filters:配置局部过滤器的 - id: provider # 静态路由:直接写死的服务提供方的路径 # uri: http://localhost:8002 # 动态路由:从EurekaServer上获取的路经,PROVIDER是服务提供方的EurekaServer上注册的name,必须大写 uri: lb://ROVIDER predicates: #/student/路径下的某个处理器 - Path=/find/** #filters: #集合参数,局部过滤器,实现一系列的前置后置的处理 # - AddRequestParameter=username,zhangsan #参数username赋值张三 - id: consumer # uri: http://localhost:8001 uri: lb://CONSUMER predicates: - Path=/consumer/** # 微服务名称配置:开启后必须配置服务的名称:http://localhost/服务的名字/consumer/feign//2 discovery: locator: enabled: true # 服务名字必须为大写:http://localhost/CONSUMER/consumer/feign//2 #lower-case-service-id: true # 服务名字必须小写:http://localhost/consumer/consumer/feign//2 ##注册到EurekaServer上获取相关的路径端口信息 eureka: client: service-url: defaultZone: http://localhost:8761/eureka,http://localhost:8762/eurekaq
全局过滤器(实现接口GlobalFilter, Ordered,并且让ioc容器识别):
/**
* 配置全局过滤器:无需任何配置,完成编码会自动识别
* 需要被ioc识别
*/
@Component
public class Filter implements GlobalFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
/**
* 做全局的相关操作
*/
//处理完相应的业务需要放行
return chain.filter(exchange);
}
/**
* 排序
* @return 返回数字越小会先执行
*/
@Override
public int getOrder() {
return 0;
}
}
启动类:
@EnableEurekaClient
@SpringBootApplication
public class GatewayApp {
public static void main(String[] args) {
SpringApplication.run(GatewayApp.class,args);
}
}
其他模块不需要做改动:
然后就可以通过网关访问微服务:
如路径:http://localhost/PROVIDER/find/2,http://localhost/consumer/feign//2
全局过滤器的添加是一个重量级的操作,添加局部过滤器参考官方文档:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.0.RELEASE/single/spring-cloud-gateway.html#_gatewayfilter_factories
自备参考文档:链接:https://pan.baidu.com/s/1OaboaCoK8u608JQEh0LpJg
提取码:myname
概述:这个组件主要是动态的更新各个微服务的配置文件用的,但是只单纯的使用这个去更新配置文件比较的繁琐,还需要结合bus(中间需要mq搭配)组件一起进行配置文件的更新!!!
这些他喵的都是为运维服务的!若是没有明确的要求,一般搭建微服务实在是懒得弄这个,配置文件太烦太烦,多还繁琐...................烦死了!
实现原理,搭建git仓库,然后在微服中搭建一个ConfigServer(pom3)服务,将git仓库绑定到ConfigServer,将该服务注册到EurekaServer上(EurekaClient依赖)!然后在各个需要动态更新配置文件的微服务上引入ConfigClient(pom1),同时需要添加SpringBoot的健康监控组件(pom2),在获取配置文件数据的类上添加@RefreshScope注解,开启动态刷新,其实核心还是使用Spring的健康监控!
刷新哪个微服务执行哪个微服务的请求,例如: http://localhost:8001/actuator/refresh
上面的 这个请求链接的只用根据项目改主机和端口,使用post发起请求即可(postman或者使用命令:curl -X POST http://localhost:8001/actuator/refresh )
pom1:
org.springframework.cloud spring-cloud-starter-config
pom2:
org.springframework.boot spring-boot-starter-actuator
pom3:
org.springframework.cloud spring-cloud-config-server
配置文件参考,ConfigServer的配置文件名字为bootstrap,yml(这个名字的配置文件居然他喵的优先于application.*的配置文件):具体的配置参考百度吧,有点烦,用到了去百度吧!!!!!一般这个轮不到我配置,除非真他喵的没人了!太多了,记不住了,也不想整理这块的啦,
最主要的是知道这个东西干嘛的,大概咋用,百度贼多!!!!
简述:其实就是为了解决使用Config每次更新配置文件还需要去每个微服务都执行请求刷新,实现原理其实就是mq,通过发送刷新命令到mq消息队列实现刷新呗!
需要搭建mq.兔子mq最好搭建了,啦啦啦啦,火箭mq还行,卡福卡,没用过,但是应该真的卡,不然不会叫卡福卡!!!!!!!!!!!!!!!!!!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~卡 !
简述:构建消息驱动微服务...........还是开发无感知的........
简述:sleuth负责收集微服务请求链的相关参数(主要还是效率检测),Zipkin负责将前者收集的数据做web控制台的展示,还是服务运维的...
具体搭建,......啦啦啦啦,百度吧!好像只是jar包,跑起来就行!微服务需要导入相关坐标!
完结:9~~~~12似乎更偏向运维,接触的不是很深,基本上完事
前面的案例代码包:链接:https://pan.baidu.com/s/1eyt9UX_rq_iTZ4b-FKJHrQ
提取码:MyReallyName
用到相关的组件,主要是配置文件,参考修改即可啦啦啦啦啦!!!!!!!!