Spring Cloud+Eureka+Ribbon实现客户端负载均衡
2017-08-29 09:33
1246 查看
Spring Cloud+Eureka+Ribbon实现客户端负载均衡
最近在学习springcloud,自己总结的客户端负载均衡,拿出来分享下eureka高可用注册中心
服务提供者
服务发现及消费
负载均衡
搭建eureka高可用注册中心
pom文件,引入spring-cloud-starter-eureka-server 注册中心的核心依赖;最后的Build标签是需要打包成jar包需要的依赖。<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.eurekaDemo</groupId> <artifactId>eurekaDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>eurekaDemo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
创建启动类EurekaDemoSpring类,其中EnableEurekaServer注解表明其为注册中心
@EnableEurekaServer //表示注册中心 @SpringBootApplication public class EurekaDemoApplication { public static void main(String[] args) { SpringApplication.run(EurekaDemoApplication.class, args); }
新建application.peer1.properties配置文件,作为peer1的服务中心配置,并将serverUrl指向peer2,其中register-with-eureka=true注册中心可以注册自己
spring.application.name=eureka-server1 server.port=1111 eureka.client.register-with-eureka=true eureka.client.fetch-registry=true eureka.instance.hostname=peer1 eureka.client.serviceUrl.defaultZone=http://peer2:1112/eureka/
同理,新建peer2注册中心
spring.application.name=eureka-server2 server.port=1112 eureka.client.register-with-eureka=true eureka.client.fetch-registry=true eureka.instance.hostname=peer2 eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/
这样,即可形成一对互相注册的高可用注册中心, 在访问之前我们需要修改下hosts文件,添加
127.0.0.1 peer1 127.0.0.1 peer2
maven打包程序 mvn install,之后找到jar包位置,以java -xxx.jar方式分别启动peer1与peer2
java -xxx.jar --spring.profiles.active=peer1 java -xxx.jar --spring.profiles.active=peer2
此时访问localhost:1111即可看到注册的服务
编写服务提供者
注册中心搭建完成后,我们继续搭建服务提供者,编写pom文件,引入注册服务提供者核心依赖spring-cloud-starter-eureka<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.springboot</groupId> <artifactId>springbootDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springbootDemo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
编写主类文件
@EnableDiscoveryClient //激活Eureka中DiscoveryClient实现,通过其可获取服务信息 @SpringBootApplication public class SpringbootDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringbootDemoApplication.class,args); } }
新建一个控制类,其中DiscoveryClient可以获取注册中心注册的服务
@RestController public class HelloController { private final Logger logger = Logger.getLogger(getClass()); @Autowired private DiscoveryClient discoveryClient; @RequestMapping(value = "/hello",method = RequestMethod.GET) public String index(){ ServiceInstance instance = discoveryClient.getLocalServiceInstance(); logger.info("++++++++++++++++++++++++++++"+instance.getServiceId()); return "Hello"; } }
编写application.properties将服务注册到注册中心
spring.application.name=hello-service eureka.client.service-url.defaultZone=http://peer1:1111/eureka,http://peer2:1112/eureka
同样我们将其打成jar包,分别以8081及8082端口启动两个服务提供者,为后续的服务消费负载均衡做准备
java -jar xxx.jar --serveer.port=8081 java -jar xxx.jar --serveer.port=8082
启动后刷新localhost:1111可看到有四个服务,如下图
这样服务提供者也编写完成,下面我们完成服务发现及消费
服务发现与消费
服务发现由Eureka实现,服务消费由Ribbon实现,我们新建一个基础的springboot项目,起名为ribbon-consumer;编写pom文件,引入Ribbon依赖spring-cloud-starter-ribbon;
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ribbon.consumer</groupId> <artifactId>ribbon-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>ribbon-consumer</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
新建应用主类RibbonConsumerApplication,其中@EnableDiscoveryClient注解表示其为客户端应用,并且需要开启客户端负载均衡@LoadBalanced
@EnableDiscoveryClient //eureka客户端应用 @SpringBootApplication public class RibbonConsumerApplication { @Bean @LoadBalanced //开启客户端负载均衡 RestTemplate restTemplate(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(RibbonConsumerApplication.class, args); } }
新建controller类,可以看到服务地址是服务名加访问路径,这在服务治理框架中是一个非常重要的特性;
@RestController public class ConsumerController { @Autowired RestTemplate restTemplate; @RequestMapping(value = "/helloConsumer",method = RequestMethod.GET) public String helloConsumer(){ return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody(); } }
编写application配置文件
spring.application.name=ribbon-consumer server.port=9000 eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
启动此应用,我们在eureka面板可以看到我们的ribbon服务
通过访问http://localhost:9000/helloConsumer 成功返回Hello,此时可以看到控制台输出了所有服务的实例信息、第一次连接信息、上次连接信息等重要数据,尝试发送多次请求,可以看到8081与8082服务轮流输出日志,以此可以判断ribbon帮我们实现了客户端负载均衡
负载均衡机制
上面实现了最简单的负载均衡,负载均衡有很多负载机制1. RandomRule:随机轮询策略,查询所有的服务列表allList与可用实例列表upLIst,根据 random.netInt(allLIst.size())作为参数i,来upList[i]的服务实例,可能会出现死循环导致BUG
2. RoundRobinRule:线性轮询策略。通过调用递增函数查找服务例;循环查询次数超过10次,则停止查询,并返回警告
3. RetryRule:重试机制的实例选择。实现在deadline时间内,不断尝试去查询实例,若时间段内未找到实例, 则返回null;
4. WeightedResponseTimeRule:权重策略。是RoundRobinRule扩展,会根据实例运行情况来计算权重,以此来挑选权重,包括是三个核心内容
5. BestAvailableRule:最闲策略;他通过遍历均衡器所有实例,过滤掉故障实例,找出并发请求数目最小的一个,即找到最闲的实例
6. PredicateBasedRule:抽象策略。首先过滤一些服务实例,然后再以线性轮询的方式选出一个实例
相关文章推荐
- Spring Cloud 入门教程(五): Ribbon实现客户端的负载均衡
- Spring Cloud Ribbon实现客户端负载均衡的示例
- 客户端实现负载均衡:springCloud Ribbon的使用
- 详解spring cloud中使用Ribbon实现客户端的软负载均衡
- Spring Cloud Ribbon实现客户端负载均衡的方法
- 微服务框架Spring Cloud介绍 Part4: 使用Eureka, Ribbon, Feign实现REST服务客户端
- 客户端负载均衡 Spring Cloud Ribbon
- Spring Cloud 客户端负载均衡之Ribbon(三)
- 【SpringCloud】Netflix源码解析之Ribbon:负载均衡策略的定义和实现
- 服务注册发现Eureka之三:Spring Cloud Ribbon实现客户端负载均衡(客户端负载均衡Ribbon之三:使用Ribbon实现客户端的均衡负载)
- SpringCloud客户端负载均衡Ribbon
- springcloud ribbon实现负载均衡的时候,提示Request URI does not contain a valid hostname: http://PRODUCT_SERVICE/
- spring cloud 之 客户端负载均衡Ribbon深入理解
- 客户端负载均衡Ribbon之一:Spring Cloud Netflix负载均衡组件Ribbon介绍
- 负载均衡之Spring Cloud Ribbon
- spring cloud中使用Ribbon实现客户端的软负载均衡
- spring cloud中Ribbon自定义负载均衡策略
- Spring Cloud微服务开发笔记5——Ribbon负载均衡策略规则定制
- Spring Cloud入门教程-Ribbon实现客户端负载均衡
- springcloud ribbon搭建服务负载均衡