1、ribbon 是什么?用来干嘛?
ribbon 是一个负载均衡组件,当我们的服务有是集群部署的时候,我们可以使用ribbon来进行负载均衡。
2、不存在服务注册与发现中心场景使用spring-cloud-netflix-ribbon
项目结构:
方式1: 使用LoadBalancerClient 来进行服务选者,服务调用链路user-service --------------------> order-service
1、user-service项目maven依赖引入:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>需要依赖spring-cloud-starter-netflix-ribbon jar包<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></dependency><dependency><groupId>com.wzy</groupId><artifactId>order-api</artifactId><version>${project.version}</version></dependency>
2、user-service 微服务启动类:
@SpringBootApplicationpublic class UserServiceRibbonApplication {public static void main(String[] args) {SpringApplication.run(UserServiceRibbonApplication.class, args);}}
3、user-service中演示的Controller:
@RestControllerpublic class UserLoabBalancerClientGetServerInstanceController {@Autowiredprivate RestTemplate restTemplate;@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}spring-cloud-starter-netflix-ribbon 会自动装配一个LoadBalancerClient在上下文中,类型是RibbonLoadBalancerClient@Autowiredprivate LoadBalancerClient loadBalancerClient;@GetMapping("userGetOrderById")public OrderDto userGetOrderById(@RequestParam("orderId") String orderId){/*使用负载均衡客户端进行服务选择,按照服务的id进行选择,服务的列表我们使用配置的方式:order-service.ribbon.listOfServers=http://localhost:7071,http://localhost:7072在后续集成服务注册与发现的时候就不需要这样配置了*/ServiceInstance serviceInstance = loadBalancerClient.choose("order-service");System.out.println(serviceInstance.getHost());System.out.println(serviceInstance.getPort());String url = String.format("http://%s:%s/getOrderById?orderId=%s", serviceInstance.getHost(), serviceInstance.getPort(), orderId);ResponseEntity<OrderDto> forEntity = restTemplate.getForEntity(url, OrderDto.class);return forEntity.getBody();}@PostMapping("userSaveOrder")public OrderDto userSaveOrder(@RequestBody OrderDto orderDto){ServiceInstance serviceInstance = loadBalancerClient.choose("order-service");System.out.println(serviceInstance.getHost());System.out.println(serviceInstance.getPort());String url = String.format("http://%s:%s/saveOrder", serviceInstance.getHost(), serviceInstance.getPort());OrderDto forObject = restTemplate.postForObject(url, orderDto, OrderDto.class);return forObject;}}
4、user-service 服务中的 application.properties:
server.port= 8080spring.application.name=user-service#由于为集成服务注册于发现,因此在配置文件中维护order-service 服务的列表order-service.ribbon.listOfServers=http://localhost:7071,http://localhost:7072
方式2:使用@LoadBalanced注解来赋予RestTemplate实例具备负载均衡的功能,服务调用链路user-service --------------------> order-service
1、user-service中演示的Controller:其他的都不变化。
@RestControllerpublic class UserController {@Autowiredprivate RestTemplate restTemplate;//使用@LoadBalanced注解来赋予此RestTemplate 具备负载均衡功能。@LoadBalanced@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}@GetMapping("userGetOrderById")public OrderDto userGetOrderById(@RequestParam("orderId") String orderId){//使用具备负载均衡功能的RestTemplate进行http服务调用ResponseEntity<OrderDto> forEntity = restTemplate.getForEntity("http://order-service/getOrderById?orderId=" + orderId, OrderDto.class);return forEntity.getBody();}@PostMapping("userSaveOrder")public OrderDto userSaveOrder(@RequestBody OrderDto orderDto){//使用具备负载均衡功能的RestTemplate进行http服务调用OrderDto forObject = restTemplate.postForObject("http://order-service/saveOrder", orderDto, OrderDto.class);return forObject;}}
3、如果存在服务注册中心,例如eureka,那么ribbon 会默认去eureka上获取服务列表,那是因为eureka默认就与ribbon做了集成,我们可以引入eureka的客户端进行验证:
maven依赖:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
我们直接查看spring-cloud-starter-netflix-eureka-client项目的pom文件:
. . .<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-archaius</artifactId><version>2.2.5.RELEASE</version><scope>compile</scope></dependency>pring-cloud-starter-netflix-eureka-client中默认将ribbon做了集成。<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId><version>2.2.5.RELEASE</version><scope>compile</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId><version>2.2.5.RELEASE</version><scope>compile</scope></dependency><dependency><groupId>com.netflix.ribbon</groupId><artifactId>ribbon-eureka</artifactId><version>2.3.0</version><scope>compile</scope><exclusions><exclusion><artifactId>annotations</artifactId><groupId>com.google.code.findbugs</groupId></exclusion><exclusion><artifactId>servlet-api</artifactId><groupId>javax.servlet</groupId></exclusion></exclusions></dependency>. . .
4、存在服务注册与发现中心场景使用spring-cloud-netflix-ribbon
我们使用eureka来作为服务注册于发现中心,项目结构:
1、eureka-server服务:
pom文件:
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
启动类:
@SpringBootApplication@EnableEurekaServerpublic class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class, args);}}
配置文件application.properties
spring.application.name=eureka-serverserver.port=9090eureka.client.register-with-eureka=falseeureka.client.fetch-registry=false
2、order-service 服务:
pom文件:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>com.wzy</groupId><artifactId>order-api</artifactId><version>${project.version}</version></dependency></dependencies>
启动类:
@SpringBootApplication@EnableEurekaClientpublic class OrderServiceRibbonApplication {public static void main(String[] args) {SpringApplication.run(OrderServiceRibbonApplication.class, args);}}
配置文件application.properties:
server.port= 7071spring.application.name=order-serviceeureka.client.service-url.defaultZone = http://localhost:9090/eureka
3、user-service服务:
pom文件:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>com.wzy</groupId><artifactId>order-api</artifactId><version>${project.version}</version></dependency></dependencies>
启动类:
@SpringBootApplication@EnableDiscoveryClientpublic class UserServiceRibbonApplication {public static void main(String[] args) {SpringApplication.run(UserServiceRibbonApplication.class, args);}}
配置文件application.properties:
server.port= 8080spring.application.name=user-serviceeureka.client.service-url.defaultZone = http://localhost:9090/eureka不在配置文件中维护order-service服务提供者列表了#order-service.ribbon.listOfServers=http://localhost:7071,http://localhost:7072
演示Controller:
@RestControllerpublic class UserController {@Autowiredprivate RestTemplate restTemplate;@LoadBalanced@Beanpublic RestTemplate restTemplate(){RestTemplate restTemplate = new RestTemplate();return restTemplate;}@GetMapping("userGetOrderById")public OrderDto userGetOrderById(@RequestParam("orderId") String orderId){//使用具备负载均衡功能的RestTemplate进行http服务调用ResponseEntity<OrderDto> forEntity = restTemplate.getForEntity("http://order-service/getOrderById?orderId=" + orderId, OrderDto.class);return forEntity.getBody();}@PostMapping("userSaveOrder")public OrderDto userSaveOrder(@RequestBody OrderDto orderDto){//使用具备负载均衡功能的RestTemplate进行http服务调用OrderDto forObject = restTemplate.postForObject("http://order-service/saveOrder", orderDto, OrderDto.class);return forObject;}}