项目搭建在上一篇Eureka集群中已经完成
添加模块eureka-ribbon-client,与之前的eureka-client一样
pom
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.wxz</groupId>
<artifactId>springcloud-demo2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--<groupId>com.wxz</groupId>和parent相同就不需要了-->
<artifactId>eureka-ribbon-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-ribbon-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--web功能起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Eureka Client所需的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!--Eureka Client负载均衡所需ribbon的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
application:
name: eureka-ribbon-client
server:
port: 8764
eureka:
client:
serviceUrl:
serverZone: http://localhost:8761/eureka/ #服务注册中心的ip
注入RestTemplate的bean:
package com.wxz.eurekaribbonclient.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author Wangxingze
* @date 2019-08-21 22:11
*/
@Configuration
public class RibbonConfig {
@Bean
@LoadBalanced //Ribbon负载均衡
RestTemplate restTemplate(){
return new RestTemplate();
}
}
创建service:请求消费服务
package com.wxz.eurekaribbonclient.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class RibbonService {
@Autowired
private RestTemplate template;
public String sayHello(String name){
//路径中使用的是服务名 ,即服务提供者的 application: name
return template.getForObject("http://eureka-client/sayHello?name=wangxingze",String.class)+"???";
}
}
编写controller调用
package com.wxz.eurekaribbonclient.controller;
import com.wxz.eurekaribbonclient.service.RibbonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Wangxingze
* @date 2019-08-21 22:29
*/
@RestController
public class RibbonController {
@Autowired
private RibbonService ribbonService;
@GetMapping(value = "/ribbonSayHello")
public String sayHello(@RequestParam(required = false,defaultValue = "default") String name){
return ribbonService.sayHello(name);
}
}
将服务注册中心设置为单节点的形式:
修改Eureka-server的yml文件为
--- #该文件为单节点启动测试
spring:
profiles: single-node
server:
port: 8761
eureka:
instance:
hostname: single-node
client:
register-with-eureka: false #不会注册到自身
fetch-registry: false #不需要向其他节点获取注册表
serviceUrl:
defaultZone: http://localhost:8761/eureka/
--- #多profiles分割符,集群文件1
spring:
profiles: peer1
server:
port: 8761 #自己的服务端口
eureka:
instance:
hostname: peer1 #server ip
client:
#register-with-eureka: false #是否将自己注册到Eureka服务器
#fetch-registry: false #
serviceUrl:
defaultZone: http://peer2:8762/eureka/ #eureka 完整配置地址
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #eureka 完整配置地址
--- #多profiles分割符,集群文件2
spring:
profiles: peer2
server:
port: 8762 #自己的服务端口
eureka:
instance:
hostname: peer2 #ip
client:
#-with-eureka: false #是否将自己注册到Eureka服务器
#fetch-registry: false #
serviceUrl:
defaultZone: http://peer1:8761/eureka/ #eureka 完整配置地址
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #eureka 完整配置地址
Eureka-client 修改为集群,两个实列,他们就i是服务提供者:
Eureka-client的yml文件;
--- #第一个服务提供者的实列
server:
port: 8763
spring:
profiles: instance1
application:
name: eureka-client #服务名 服务提供者需要提供,远程调用时使用
eureka:
client:
serviceUrl:
#defaultZone: http://peer1:8761/eureka/ #Eureka Server的注册地址
defaultZone: http://localhost:8761/eureka/ #Eureka Server的注册地址
--- #第二个服务提供者的实列
server:
port: 8765
spring:
profiles: instance2
application:
name: eureka-client #服务名 服务提供者需要提供,远程调用时使用
eureka:
client:
serviceUrl:
#defaultZone: http://peer1:8761/eureka/ #Eureka Server的注册地址
defaultZone: http://localhost:8761/eureka/ #Eureka Server的注册地址
使用上一篇集群中所说的集群启动方法:
依次创建一个服务注册中心、两个服务提供者实列、一个消费者;依次启动(记得加启动类注解)
都已成功注册
第一次访问:
第二次:
可见端口会改变,Ribbon将服务请求轮流分发到两个提供者
LoadBalancerClient应用:
将service改为面向接口编程,注意@Service需要加在实现类上才有效
service实现:
package com.wxz.eurekaribbonclient.service.ServiceImpl;
import com.wxz.eurekaribbonclient.service.RibbonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
/**
* @author Wangxingze
* @date 2019-08-21 23:21
*/
@Service
public class RibbonServiceImpl implements RibbonService {
@Autowired
private RestTemplate template;
@Autowired
private LoadBalancerClient balancerClient;
@Override
public String sayHello(String name){
//路径中使用的是服务名 ,即服务提供者的 application: name
return template.getForObject("http://eureka-client/sayHello?name="+name,String.class)+"???";
}
@Override
public String testBalanceClient(){
ServiceInstance serviceInstance=balancerClient.choose("eureka-client");
StringBuilder stringBuilder=new StringBuilder();
stringBuilder.append("Host:");
stringBuilder.append(serviceInstance.getHost());
stringBuilder.append(" PORT:");
stringBuilder.append(serviceInstance.getPort());
return stringBuilder.toString();
}
}
controller添加方法:
@GetMapping(value = "/testloadBalancerClient")
public String testloadBalancerClient(){
return ribbonService.testBalanceClient();
}
第一次访问:
第二次: