springcloud入门
SpringCloud简介
以下来自百度百科:Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
主要分为以下五个部分,本次主要讲解服务的发现与注册—Eureka与客户端负载均衡—Ribbon,再通过搭建工程来展示。
-
服务发现与注册——Netflix Eureka
-
客服端负载均衡——Netflix Ribbon
-
断路器——Netflix Hystrix
-
服务网关——Netflix Zuul
-
分布式配置——Spring Cloud Config
下面我先简要的对Eureka即Ribbon做一个介绍,具体的代码以及配置文件在后面的案例中再来展示
一、Eureka注册中心——Eureka Server
在我们现在的前后端分离架构中,服务层被拆分成了很多的微服务,这时候SpringCloud中提供了服务注册中心来管理微服务信息。
功能:
- 注册中心帮我们管理微服务的ip和端口,进行远程调用服务
- 微服务实时上报自己的状态,注册中心统一管理这些微服务的状态,将存在问题的服务踢出服务列表,客户端获取到可用的服务进行调用
Eureka介绍:
Spring Cloud Eureka提供服务端与客户端,服务端即是Eureka服务注册中心,客户端完成微服务向Eureka服务的注册与发现。服务端和客户端均采用Java语言的编写,下图是服务端与客户端之间的关系:
1、Eureka Server是服务端,负责管理各微服务节点的信息和状态,就是作为一个注册中心的功能
2、在微服务上部署Eureka Client程序,远程访问Eureka Server将自己注册在Eureka Server上
3、微服务需要调用另一个微服务时从Eureka Server中获取服务调用地址,进行远程调用其他的微服务
总结:就是Eureka Server作为一个注册中心,所有的Eureka Client作为微服务的提供者将服务注册到Eureka Server中来让其他的微服务进行调用。为服务工程同时充当服务者与消费者两种角色,只是看在一个服务进程当中所起的作用。
-
Eureka Server工程搭建:
- 作为注册中心的Eureka Server工程中需要
- 添加eureka-server的依赖
- 在启动类上加上EnableEurekaServer注解标识这是一个Eureka的服务
- 配置文件中配置相关eureka的参数
- Eureka Server的高可用环境:
- 我们至少部署两个Eureka Server,端口号设置为不一样,相互向对方注册
- 在实际使用时Eureka Server至少部署两台服务器,实现高可用
- 两台Eureka Server相互注册
- 微服务需要连接两台Eureka Server,当其中一台Eureka死掉也不会影响服务的注册与发现
- 微服务会定时向Eureka Server发送心跳,报告自己的状态
- 微服务从注册中心获取服务地址以Restful方式发起远程调用
二、eureka客户端——Eureka Client
eureka的客户端中,微服务工程将服务注册到注册中心,通过注册中心获取其他为微服务的猪血信息,调用与被调用其他的微服务。
- Eureka Client工程搭建:
- 配置服务的提供者,添加eureka-client的依赖
- 配置文件中配置相关eureka Client的参数
- 启动类上添加注解@EnableDiscoveryClient,表示这是一个Eureka客户端
- 在我们需要实现负载均衡调用服务的时候需要创建一个以上的工程来提供同一个服务,这些工程有不同的端口号以及相同的服务名称
三、远程调用——Ribbon
在前后端的分离架构中,服务层被拆分成很多的微服务,服务与服务之间相互交互,就是远程调用的过程。
- 首先我们的工程也是一个Eureka Client的客户端
- 服务调用端将自己注册到注册中心
- 从注册中心获取自己需要的服务的地址 远程调用服务 ---- 调用服务中的消费者与服务提供者是一个相对的概念
- 在自己调用其他工程的服务时,自己充当的是消费者的角色,被调用方充当的是服务提供者的角色
- 反之,当自己被其他工程调用是,角色则发生了反转
- 但是,相对于Eureka来讲,不管是消费者还是服务提供者都是作为Eureka的客户端
1.Ribbon
一个基于Http、TCP的客户端负载均衡器。不同于我们了解的Nginx等是作为服务端负载均衡器。Ribbon负载均衡的流程图如下:
- 在消费为服务使用Ribbon实现负载均衡,Ribbon先从EurekaServer中获取服务列表
- Ribbon根据负载均衡算法去调用微服务
- Ribbon的远程调用是由RestTemplate提供的,而RestTemplate又基于HttpClient、OKHttp等
使用Ribbon的功能需要:
- 在工程中引入ribbon以及OKHttp(或者其他能工提供远程访问请求的底层客户端)的依赖
- 在配置文件中配置ribbon的相关参数
- 在启动类中上同样需要配置@EnableDiscoveryClient注解来表示自己为Eureka的客户端
- 创建bean对象RestTemplate,在RestTemplate上使用注解@LoadBalance(标识使用Ribbon的注解)
2、feign
底层封装了Ribbon,通过定义接口加上Feign的注解,通过代理的方式创建出接口的实现类,通过调用接口接口中的方法来实现远程调用。
- 需引入Feign(Feign中封装了Ribbon)以及OKHttp的依赖
- 创建被@FeignCLient注解标识的接口——Feign通过代理的方式提供其实现类,调用定义好的方法来实现远程访问
- 配置文件中同样是配置Ribbon的相关配置
四、案例
- 搭建一个总工程:springcloud-demo:引入一些基本依赖
- 搭建两个Eureka Server的module:eureka01和eureka02,两个module相互注册,形成一个高可用的环境
- 搭建两个Eureka Client的module:micro-service01和micro-service02,两个module提供一样的服务,实现在负载均衡条件下的调度
- 搭建一个Eureka Client的modole:ribbonRequest,用于测试ribbon作为负载均衡器的实现
- 搭建一个Eureka Client的module:feignRequest,用于测试feign作为负载均衡器的实现
- 整个工程的架构如下:
1.创建springcloud-demo工程,引入依赖
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.buwei</groupId> 8 <artifactId>springcloud-demo</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 <modules> 11 <module>eureka01</module> 12 <module>eureka02</module> 13 <module>micro-service01</module> 14 <module>micro-service02</module> 15 <module>ribbon-request</module> 16 <module>feign-request</module> 17 </modules> 18 <packaging>pom</packaging> 19 20 <parent> 21 <groupId>org.springframework.boot</groupId> 22 <artifactId>spring-boot-starter-parent</artifactId> 23 <version>2.1.1.RELEASE</version> 24 <relativePath/> <!-- lookup parent from repository --> 25 </parent> 26 27 <properties> 28 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 29 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 30 <java.version>1.8</java.version> 31 <spring-cloud.version>Finchley.SR1</spring-cloud.version> 32 </properties> 33 34 <dependencyManagement> 35 <dependencies> 36 <dependency> 37 <groupId>org.springframework.cloud</groupId> 38 <artifactId>spring-cloud-dependencies</artifactId> 39 <version>${spring-cloud.version}</version> 40 <type>pom</type> 41 <scope>import</scope> 42 </dependency> 43 </dependencies> 44 </dependencyManagement> 45 46 <build> 47 <plugins> 48 <plugin> 49 <groupId>org.springframework.boot</groupId> 50 <artifactId>spring-boot-maven-plugin</artifactId> 51 </plugin> 52 </plugins> 53 </build> 54 55 <repositories> 56 <repository> 57 <id>spring-milestones</id> 58 <name>Spring Milestones</name> 59 <url>https://repo.spring.io/milestone</url> 60 <snapshots> 61 <enabled>false</enabled> 62 </snapshots> 63 </repository> 64 </repositories> 65 66 67 </project>
2.搭建eureka01和eureka02工程
- eureka01工程:
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>springcloud-demo</artifactId> 7 <groupId>com.buwei</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>eureka01</artifactId> 13 <version>1.0-SNAPSHOT</version> 14 15 <dependencies> 16 <dependency> 17 <groupId>org.springframework.cloud</groupId> 18 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> 19 </dependency> 20 21 <dependency> 22 <groupId>org.springframework.boot</groupId> 23 <artifactId>spring-boot-starter-web</artifactId> 24 </dependency> 25 26 <dependency> 27 <groupId>org.springframework.boot</groupId> 28 <artifactId>spring-boot-starter-test</artifactId> 29 <scope>test</scope> 30 </dependency> 31 </dependencies> 32 33 </project>
引导类Eureka01Application
1 @EnableEurekaServer 2 @SpringBootApplication 3 public class Eureka01Application { 4 5 public static void main(String[] args) { 6 SpringApplication.run(Eureka01Application.class, args); 7 } 8 }
配置文件
1 server: 2 port: 31001 # 服务端口 3 spring: 4 application: 5 name: springcloud-eureka # 指定服务名 6 eureka: 7 instance: 8 hostname: eureka01 9 client: 10 register-with-eureka: true # 被其他服务调用时需要向Eureka注册 11 fetch-registry: true # 服务发现,需要从Eureka查找要调用的目标服务时需要设置为true 12 service-url: # Eureka客户端与Eureka服务端的交互地址,高可用状态配置对方的地址,单机状态配置自己(如果不配置则默认本机8761端口) 13 defaultZone: http://127.0.0.1:31002/eureka/ # 类似于dubbox中的注册中心地址 14 server: 15 enable-self-preservation: false # 是否开启自我保护模式 16 eviction-interval-timer-in-ms: 60000 # 服务注册表清理间隔(单位:毫秒,默认是60*1000)
- eureka02工程
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>springcloud-demo</artifactId> 7 <groupId>com.buwei</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>eureka02</artifactId> 13 <version>1.0-SNAPSHOT</version> 14 15 <dependencies> 16 <dependency> 17 <groupId>org.springframework.cloud</groupId> 18 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> 19 </dependency> 20 21 <dependency> 22 <groupId>org.springframework.boot</groupId> 23 <artifactId>spring-boot-starter-web</artifactId> 24 </dependency> 25 26 <dependency> 27 <groupId>org.springframework.boot</groupId> 28 <artifactId>spring-boot-starter-test</artifactId> 29 <scope>test</scope> 30 </dependency> 31 </dependencies> 32 </project>
引导类
1 @EnableEurekaServer 2 @SpringBootApplication 3 public class Eureka02Application { 4 5 public static void main(String[] args) { 6 SpringApplication.run(Eureka02Application.class, args); 7 } 8 }
配置文件
1 server: 2 port: 31002 # 服务端口 3 spring: 4 application: 5 name: springcloud-eureka # 指定服务名 6 eureka: 7 instance: 8 hostname: eureka02 9 client: 10 register-with-eureka: true # 被其他服务调用时需要向Eureka注册 11 fetch-registry: true # 服务发现,需要从Eureka查找要调用的目标服务时需要设置为true 12 service-url: # Eureka客户端与Eureka服务端的交互地址,高可用状态配置对方的地址,单机状态配置自己(如果不配置则默认本机8761端口) 13 defaultZone: http://127.0.0.1:31001/eureka/ # 类似于dubbox中的注册中心地址 14 server: 15 enable-self-preservation: false # 是否开启自我保护模式 16 eviction-interval-timer-in-ms: 60000 # 服务注册表清理间隔(单位:毫秒,默认是60*1000)
3.搭建micro-service01和micro-service02工程
- micro-service01工程
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>springcloud-demo</artifactId> 7 <groupId>com.buwei</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>micro-service01</artifactId> 13 <version>1.0-SNAPSHOT</version> 14 15 <dependencies> 16 <!-- 导入Eureka客户端的依赖 --> 17 <dependency> 18 <groupId>org.springframework.cloud</groupId> 19 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 20 </dependency> 21 22 <dependency> 23 <groupId>org.springframework.boot</groupId> 24 <artifactId>spring-boot-starter-web</artifactId> 25 </dependency> 26 27 <dependency> 28 <groupId>org.springframework.boot</groupId> 29 <artifactId>spring-boot-starter-test</artifactId> 30 <scope>test</scope> 31 </dependency> 32 </dependencies> 33 </project>
引导类MicroService01Application
1 @EnableDiscoveryClient 2 @SpringBootApplication 3 public class MicroService01Application { 4 5 public static void main(String[] args) { 6 SpringApplication.run(MicroService01Application.class, args); 7 } 8 }
controller层MicroService01Controller
1 @RestController 2 public class MicroService01Controller { 3 4 /** 5 * 提供Ribbon的请求 6 * @return 7 */ 8 @GetMapping("/ribbonRequest") 9 public String testRibbonRequest(){ 10 return "MicroService01-RibbonRequest"; 11 } 12 13 /** 14 * 提供Feign的请求 15 * @return 16 */ 17 @GetMapping("/feignRequest") 18 public String testFeignRequest(){ 19 return "MicroService01-FeignRequest"; 20 } 21 }
配置文件application.yml
1 server: 2 port: 41001 3 spring: 4 application: 5 name: springcloud-micro-service 6 eureka: 7 client: 8 registerWithEureka: true #服务注册开关 9 fetchRegistry: true #服务发现开关 10 serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔 11 defaultZone: http://localhost:31001/eureka/,http://localhost:31002/eureka/ 12 instance: 13 prefer-ip-address: true #将自己的ip地址注册到Eureka服务中 14 ip-address: 127.0.0.1 15 instance-id: ${spring.application.name}:${server.port} #指定实例id
- MicroService02工程
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>springcloud-demo</artifactId> 7 <groupId>com.buwei</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>micro-service02</artifactId> 13 <version>1.0-SNAPSHOT</version> 14 15 <dependencies> 16 <!-- 导入Eureka客户端的依赖 --> 17 <dependency> 18 <groupId>org.springframework.cloud</groupId> 19 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 20 </dependency> 21 22 <dependency> 23 <groupId>org.springframework.boot</groupId> 24 <artifactId>spring-boot-starter-web</artifactId> 25 </dependency> 26 27 <dependency> 28 <groupId>org.springframework.boot</groupId> 29 <artifactId>spring-boot-starter-test</artifactId> 30 <scope>test</scope> 31 </dependency> 32 </dependencies> 33 </project>
引导类MicroService02Application
1 @EnableDiscoveryClient 2 @SpringBootApplication 3 public class MicroService02Application { 4 5 public static void main(String[] args) { 6 SpringApplication.run(MicroService02Application.class, args); 7 } 8 }
controller层MicroService02Controller
1 @RestController 2 public class MicroService02Controller { 3 4 @GetMapping("/ribbonRequest") 5 public String testRibbonRequest(){ 6 return "MicroService02-RibbonRequest"; 7 } 8 9 @GetMapping("/feignRequest") 10 public String testFeignRequest(){ 11 return "MicroService02-FeignRequest"; 12 } 13 }
配置文件application.yml
1 server: 2 port: 41002 3 spring: 4 application: 5 name: springcloud-micro-service 6 eureka: 7 client: 8 registerWithEureka: true #服务注册开关 9 fetchRegistry: true #服务发现开关 10 serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔 11 defaultZone: http://localhost:31001/eureka/,http://localhost:31002/eureka/ 12 instance: 13 prefer-ip-address: true #将自己的ip地址注册到Eureka服务中 14 ip-address: 127.0.0.1 15 instance-id: ${spring.application.name}:${server.port} #指定实例id
4、Ribbon测试工程ribbon-request
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>springcloud-demo</artifactId> 7 <groupId>com.buwei</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>ribbon-request</artifactId> 13 <version>1.0-SNAPSHOT</version> 14 15 <dependencies> 16 <!-- 导入Eureka客户端的依赖 --> 17 <dependency> 18 <groupId>org.springframework.cloud</groupId> 19 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 20 </dependency> 21 22 <!--引入ribbon的依赖--> 23 <dependency> 24 <groupId>org.springframework.cloud</groupId> 25 <artifactId>spring-cloud-starter-ribbon</artifactId> 26 <version>RELEASE</version> 27 </dependency> 28 29 <!--ribbon发起远程调用的底层客户端--> 30 <dependency> 31 <groupId>com.squareup.okhttp3</groupId> 32 <artifactId>okhttp</artifactId> 33 </dependency> 34 35 <dependency> 36 <groupId>org.springframework.boot</groupId> 37 <artifactId>spring-boot-starter-web</artifactId> 38 </dependency> 39 40 <dependency> 41 <groupId>org.springframework.boot</groupId> 42 <artifactId>spring-boot-starter-test</artifactId> 43 <scope>test</scope> 44 </dependency> 45 </dependencies> 46 47 </project>
引导类:RibbonRequestApplication
1 @EnableDiscoveryClient 2 @SpringBootApplication 3 public class RibbonRequestApplication { 4 5 public static void main(String[] args) { 6 SpringApplication.run(RibbonRequestApplication.class, args); 7 } 8 9 @Bean 10 @LoadBalanced 11 public RestTemplate restTemplate(){ 12 return new RestTemplate(); 13 } 14 }
配置文件:application.yml
1 server: 2 port: 8080 #\u8BF7\u6C42\u5904\u7406\u7684\u8D85\u65F6\u65F6\u95F4 3 spring: 4 application: 5 name: consumer 6 eureka: 7 client: 8 registerWithEureka: true #服务注册开关 9 fetchRegistry: true #服务发现开关 10 serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔 11 defaultZone: http://localhost:31001/eureka/,http://localhost:31002/eureka/ 12 instance: 13 prefer-ip-address: true #将自己的ip地址注册到Eureka服务中 14 ip-address: 127.0.0.1 15 instance-id: ${spring.application.name}:${server.port} #指定实例id 16 ribbon: 17 MaxAutoRetries: 2 #最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试 18 MaxAutoRetriesNextServer: 3 #切换实例的重试次数 19 OkToRetryOnAllOperations: false #对所有操作请求都进行重试,如果是get则可以,如果是post,put等操作 20 #没有实现幂等的情况下是很危险的,所以设置为false 21 ConnectTimeout: 5000 #请求连接的超时时间 22 ReadTimeout: 6000 #请求处理的超时时间
测试类:RibbonTest
1 @SpringBootTest 2 @RunWith(SpringRunner.class) 3 public class RibbonTest { 4 @Autowired 5 private RestTemplate restTemplate; 6 7 @Test 8 public void testRibbon(){ 9 String name = "springcloud-micro-service"; // 大小写均可 10 for (int i = 0; i < 10; i++) { 11 ResponseEntity<String> forEntity = restTemplate.getForEntity("http://"+name+"/ribbonRequest", String.class); 12 String body = forEntity.getBody(); 13 System.out.println(body); 14 } 15 16 } 17 }
5、feign测试工程feign-request
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>springcloud-demo</artifactId> 7 <groupId>com.buwei</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>feign-request</artifactId> 13 <version>1.0-SNAPSHOT</version> 14 15 <dependencies> 16 <!-- 导入Eureka客户端的依赖 --> 17 <dependency> 18 <groupId>org.springframework.cloud</groupId> 19 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 20 </dependency> 21 22 <dependency> 23 <groupId>org.springframework.cloud</groupId> 24 <artifactId>spring-cloud-starter-feign</artifactId> 25 <version>RELEASE</version> 26 </dependency> 27 <dependency> 28 <groupId>com.squareup.okhttp3</groupId> 29 <artifactId>okhttp</artifactId> 30 </dependency> 31 32 <dependency> 33 <groupId>org.springframework.boot</groupId> 34 <artifactId>spring-boot-starter-web</artifactId> 35 </dependency> 36 37 <dependency> 38 <groupId>org.springframework.boot</groupId> 39 <artifactId>spring-boot-starter-test</artifactId> 40 <scope>test</scope> 41 </dependency> 42 </dependencies> 43 44 45 </project>
引导类:FeignRequestApplication
1 @EnableFeignClients //开始feignClient 2 @EnableDiscoveryClient 3 @SpringBootApplication 4 public class FeignRequestApplication { 5 6 public static void main(String[] args) { 7 SpringApplication.run(FeignRequestApplication.class, args); 8 } 9 10 @Bean 11 @LoadBalanced 12 public RestTemplate restTemplate(){ 13 return new RestTemplate(); 14 } 15 }
实现远程调用的接口:FeignClientInterface
1 @FeignClient(value = "springcloud-micro-service") 2 public interface FeignClientInterface { 3 4 @GetMapping("/feignRequest") 5 public String feignRequest(); 6 }
配置文件:application.yml
1 server: 2 port: 8080 #\u8BF7\u6C42\u5904\u7406\u7684\u8D85\u65F6\u65F6\u95F4 3 spring: 4 application: 5 name: consumer 6 eureka: 7 client: 8 registerWithEureka: true #服务注册开关 9 fetchRegistry: true #服务发现开关 10 serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔 11 defaultZone: http://localhost:31001/eureka/,http://localhost:31002/eureka/ 12 instance: 13 prefer-ip-address: true #将自己的ip地址注册到Eureka服务中 14 ip-address: 127.0.0.1 15 instance-id: ${spring.application.name}:${server.port} #指定实例id 16 ribbon: 17 MaxAutoRetries: 2 #最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试 18 MaxAutoRetriesNextServer: 3 #切换实例的重试次数 19 OkToRetryOnAllOperations: false #对所有操作请求都进行重试,如果是get则可以,如果是post,put等操作没有实现幂等的情况下是很危险的,所以设置为false 20 ConnectTimeout: 5000 #请求连接的超时时间 21 ReadTimeout: 6000 #请求处理的超时时间
测试类:FeignTest
1 @SpringBootTest 2 @RunWith(SpringRunner.class) 3 public class FeignTest { 4 5 @Autowired 6 private FeignClientInterface feignClientInterface; 7 8 @Test 9 public void testFeign(){ 10 for (int i = 0; i < 10; i++) { 11 String s = feignClientInterface.feignRequest(); 12 System.out.println(s); 13 } 14 } 15 }
6、执行测试
- 首先开启注册中心:eureka01和eureka02,在首次执行启动类的时候控制台会打印连接不上的报错,这是因为eureka01和eureka02相互注册服务,但是在初次启动时找不到服务,属于正常现象
- 开启两个提供服务的工程micro-service01和micro-service02
- 执行RibbonTest类中的testRibbon()方法,控制台打印如下:
-
- 执行FeignTest类中的额testFeign()方法,控制台打印如下:
-
- 发现:无论是用Ribbon还是Feign,在两次测试请求服务的过程中,都是采用轮询的方式向两个提供服务的微服务工程进行调用,实现了负载均衡的调配。