1、背景
使用 zk 作为注册中心,使用 Spring cloud openfeign 进行远程调用
2、步骤
2.1 service-provider
1.Pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Eureka 服务发现与注册客户端依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Zookeeper 服务发现与注册客户端依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
</dependencies>
2. Controller
@RestController
public class EchoSerivceController {
private final Environment environment;
public EchoSerivceController(Environment environment) {
this.environment = environment;
}
//获取 随机 端口的 方法
private String getPort() {
return environment.getProperty("local.server.port"); //依赖注入时 动态 注入
}
@GetMapping("/echo/{message}")
public String echo(@PathVariable String message) {
return "[ECHO: "+ getPort() + " ] : " + message;
}
}
3 properties
spring:
application:
name: service-provider
cloud:
zookeeper:
enabled: false # Zookeeper 服务发现与注册失效(默认)
server:
port: 0 #随机端口
## 默认 profile 关闭自动特性,
eureka:
client:
enabled: false # Eureka 服务发现与注册失效(默认)
--- # Profile For Eureka
spring:
profiles: eureka
# Eureka 客户端配置
eureka:
server: # 官方不存在的配置(自定义配置)
host: 127.0.0.1
port: 12345
client:
enabled: true
serviceUrl:
defaultZone: http://${eureka.server.host}:${eureka.server.port}/eureka
registryFetchIntervalSeconds: 5 # 5 秒轮训一次
instance: # 自定义 instanceId
instanceId: ${spring.application.name}:${server.port}
--- # Profile For Zookeeper
spring:
profiles: zookeeper
cloud:
zookeeper:
enabled: true
connectString: 127.0.0.1:2181
项目启动 添加 参数。--spring.profiles.active=zookeeper, 是 zk 作为 注册中心失效
2.2 service-client
1.pom.xml
<dependencies>
<!-- 添加 spring cloud openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Eureka 服务发现与注册客户端依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Zookeeper 服务发现与注册客户端依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
</dependencies>
2. 定义 feign接口
/**
* 定义 feign 接口
*/
@FeignClient("service-provider") //应用(服务)名称, 否则 ClientException: Load balancer does not have available server for client: echoServiceClient
public interface EchoServiceClient {
//同 service-provider controller
@GetMapping("/echo/{message}")
public String echo(@PathVariable String message);
}
3. 定义client controller
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //扫描同包 package 使@FeignClient生效
@RestController
public class EchoServiceClientBootstrap {
@Autowired
private EchoServiceClient echoServiceClient;
@GetMapping(value = "/call/echo/{message}")
public String echo(@PathVariable String message) {
return echoServiceClient.echo(message);
}
public static void main(String[] args) {
SpringApplication.run(EchoServiceClientBootstrap.class, args);
}
}
3 测试
前提: 启动 zk
项目启动后,能在 zk 中看到 两个模块
[zk: localhost:2181(CONNECTED) 4] ls /services/service- service-client service-provider
异常一
Field echoServiceClient in com.gupaoedu.client.EchoServiceClientBootstrap required a bean of type 'com.gupaoedu.client.EchoServiceClient' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.gupaoedu.client.EchoServiceClient' in your configuration.
没有添加。@EnableFeignClients
异常二
[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: echoServiceClient] with root cause
com.netflix.client.ClientException: Load balancer does not have available server for client: echoServiceClient
@FeignClient("service-provider"). Value 不是 生产这的 application.name. 通过 spring.application.name 进行 实例的获取
总结
1、所有的学习,从记录开始; 所有的原理,从 使用开始
2、spring cloud feign的使用过程中,涉及很多细节: Enable 驱动模块、负载均衡实现等,后续 充实,听的时候 似懂非懂,涉及的基础太多了
参考:
小马哥视频