服务注册中心已经有了: 现在需要服务提供者和服务消费者
案例要求很简单: 消费者调用服务请求hello, 根据传入参数name, 实现返回"hello, name"即可
1. 搭建服务提供者producer
pom如下
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
配置application.properties
# 服务提供者
spring.application.name=spring-cloud-eureka-producer
server.port=9000
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
*取消了eureka.client.register-with-eureka 和eureka.client.fetch-registry的配置, 因为默认为true, 就是要将其注册到注册中心register
在项目启动类添加注解@EnableEurekaClient
编写服务
@RestController
public class ApiHello {
/*@Autowired
private LoadBalancerClient loadBalancerClient;*/
@RequestMapping(value = "/hello")
public String sayHello(HttpServletRequest request) throws IllegalAccessException {
String name = request.getParameter("name");
/*String age = request.getParameter("age");
if(age.equals("23")){
throw new IllegalAccessException("我出错了xox");
}*/
// System.out.println("我是9001");
return JSON.toJSONString("hello,"+name);
}
}
启动项目, 访问http://localhost:8000/, 注册应用出多了应用SPRING-CLOUD-EUREKA-PRODUCER
看见屏幕中间有一排红字不要慌, 那是告诉咱们没有消费者
再访问http://localhost:9000/hello?name=李四, 返回"hello,李四"说明服务正常, 开始搭建消费者
2. 搭建服务消费者consumer
pom如下, 和producer一样, 都依赖spring-cloud-starter-netflix-eureka-client
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
配置application.properties
# 服务消费者
spring.application.name=spring-cloud-eureka-consumer
server.port=9001
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
在项目启动类添加注解@EnableEurekaClient, 和提供者一样
消费者代码
基于Ribbon,Ribbon是一个客户端的负载均衡器,它提供对大量的HTTP和TCP客户端的访问控制
@RestController
public class ApiHello {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/consumer/hello")
public String hello(HttpServletRequest request) throws JsonProcessingException {
String name = request.getParameter("name");
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
map.add("name",name);
return this.restTemplate.postForObject("http://spring-cloud-eureka-producer/hello",map,String.class);
}
}
启动消费者, 浏览器访问http://localhost:8000, 看见application出现了两个应用, 一个消费者, 一个提供者. 继续访问http://localhost:9001/consumer/hello?name=%E4%BD%A0%E6%98%AF%E5%82%BB%E5%AD%90, 如果出现"hello, 你是傻子", 说明服务和消费都正常
3. 负载均衡
在提供者的服务代码中加入打印port即可
@RestController
public class ApiHello {
/*@Autowired
private LoadBalancerClient loadBalancerClient;*/
@RequestMapping(value = "/hello")
public String sayHello(HttpServletRequest request) throws IllegalAccessException {
String name = request.getParameter("name");
/*String age = request.getParameter("age");
if(age.equals("23")){
throw new IllegalAccessException("我出错了xox");
}*/
System.out.println("我是9000");
return JSON.toJSONString("hello,"+name);
}
}
启动, 修改端口号比如9002, 打印语句也改成9002, 其他都不用改,打包启动
浏览器访问http://localhost:9001//consumer/hello?name=%E4%BD%A0%E6%98%AF%E5%82%BB%E5%AD%90, 分别在控制台能看见9000端口服务打印 我是9000, 9002端口服务打印 我是9002. 轮询调用, 这也就实现了负载均衡
4. 基于feign的服务消费者
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果
可以新建一个module, 也可以在前面的消费者上面改
pom中加入spring-cloud-starter-openfeign依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<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>
application.properties不变
启动类上注解如下
@SpringBootApplication
@EnableDiscoveryClient // 启用服务注册与发现
@EnableFeignClients // 启用feign进行远程调用
新建接口
@FeignClient(value ="spring-cloud-eureka-producer")
public interface HelloService {
@RequestMapping("/hello")
String hello(@RequestParam(value = "map") Map<String,String> map);
}
controller调用该接口
@RestController
public class ApiHello {
@Autowired
HelloService helloService;
@RequestMapping("/feign/hello")
public String hello(HttpServletRequest request){
String name = request.getParameter("name");
// String age = request.getParameter("age");
Map<String, String> map = new HashMap<>();
map.put("name",name);
// map.put("age",age);
// 调用多个服务
return helloService.hello(map);
}
}
ok, 浏览器访问http://localhost:9003/feign/hello?name=%E6%9D%8E%E5%9B%9B, 结果正常即可, 当然feign也可以实现负载均衡, 启动两个服务提供者即可
over