前面说过在微服务架构中, 各个服务之间通常是基于HTTP的Restful API进行通信, Spring Cloud有两种服务调用方式,一种是Ribbon+RestTemplate,另一种是Feign,本文先将讲解前者
可以参考官方文档: http://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#spring-cloud-ribbon
Spring Cloud Netflix默认情况下为Ribbon(BeanType beanName:ClassName)提供以下bean:
Ribbon可以在通过客户端中配置的ribbonServerList服务端列表去轮询访问以达到均衡负载的作用 当Ribbon与Eureka联合使用时,ribbonServerList会被DiscoveryEnabledNIWSServerList重写,扩展成从Eureka注册中心中获取服 务端列表。同时它也会用NIWSDiscoveryPing来取代IPing,它将职责委托给Eureka来确定服务端是否已经启动
既然是负载均衡对吧 得有两个服务消费者 我们使用Idea启动多个实例即可 再启动之前设置下 我的idea版本2018.3的 选择右上角勾线即可
启动eureka-client, 端口为8762 , 然后将eureka-client的配置文件的端口改为8764,再启动, 打开浏览器: 输入 http://localhost:8761/ 这时你会发现: eureka-client在eureka-server注册了2个实例
192.168.1.103:eureka-client:8764 192.168.1.103:eureka-client:8762
端口号分别是: 8762 8764
开始创建ribbon-server服务 创建时勾选ribbon依赖
改造后的pom.xml文件 也就是继承父pom文件 和 父pom添加ribbon-server模块
<?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> <parent> <groupId>com.li</groupId> <artifactId>SpringCloudLearn</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../</relativePath> </parent> <artifactId>ribbon-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>ribbon-server</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR1</spring-cloud.version> </properties> <dependencies> <!--eureka客户端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</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>
配置文件
# 端口号server.port=8765# 需要指明spring.application.name 这个很重要# 这在以后的服务与服务之间相互调用一般都是根据这个namespring.application.name=ribbon-server#服务注册中心实例的主机名eureka.instance.hostname=localhost#服务注册中心端口号eureka.port=8761#在此指定服务注册中心地址eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${eureka.port}/eureka/
在程序入口处,通过@EnableDiscoveryClient向服务中心注册
并且向程序注入一个Bean: RestTemplate
并通过@LoadBalanced注解表明这个RestRemplate开启负载均衡的功能
并定义接口/hello 进行调用使用
package com.li.ribbonserver;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.context.annotation.Bean;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;@RestController@EnableEurekaClient@SpringBootApplicationpublic class RibbonServerApplication { public static void main(String[] args) { SpringApplication.run(RibbonServerApplication.class, args); } @Bean @LoadBalanced // 开启负载均衡 RestTemplate restTemplate() { return new RestTemplate(); } @RequestMapping("/hello") public String hello(String name) { // 地址直接写服务名称即可 return this.restTemplate().getForObject("http://eureka-client/hello?name" + name, String.class); }}
可能大家发现我之前是通过ip地址和端口号进行调用, 现在不再手动获取ip和端口,而是直接通过服务名称调用现在改为服务名进行调用了, 因为通过Ribbon和Eureka结合使用时从Eureka注册中心中获取服务端列表从而获取到服务名所对应的ip以及端口号
启动项目,打开浏览器访问: localhost:8765/hello?name=lhd 看下效果
第一次访问:
第二次访问:
通过控制台可以看到 自动获取Eurka服务中心的eurrka-client服务名对应的ip以及端口号
这样就实现了Ribbon客户端对服务调用的负载均衡
源码下载: https://github.com/LiHaodong888/SpringCloudLearn