本文demo在Spring Cloud Finchley版本Demo笔记,注册中心、服务注册、服务发现、和注册中心高可用基础上搭建。
一、RestTemplate的通信方式:
新建两个子模块,provider和consumer作为服务提供者和消费者
1、pom.xml均为:
<?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.cobra</groupId>
<artifactId>springcloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.cobra</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>provider</name>
<description>Demo project for Spring Boot</description>
<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>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、provider、consumer统一向注册中心注册的配置文件分别为为:
server:
port: 8081
spring:
application:
name: provider
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
server:
port: 8082
spring:
application:
name: consumer
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
注册中心的eureka只保留向自己注册的8761服务器和向自己注册的url。
3、在provider模块下新建controller包:
provider新建类ProviderController:
package com.cobra.provider.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author: Baron
* @Description:
* @Date: Created in 2019/3/12 16:02
*/
@RestController
@RequestMapping("/provider")
@Slf4j
public class ProviderController {
@GetMapping("/get")
public String get() {
log.info("visit getProvider!");
return "i am getProvider";
}
@PostMapping("/post")
public String post() {
log.info("visit postProvider!");
return "i am postProvider";
}
}
4、consumer模块新建config包,新建RestTemplateConfig,将RestTemplate注入,同时给方法加上@LoadBalanced负载均衡注解:
package com.cobra.consumer.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: Baron
* @Description:
* @Date: Created in 2019/3/12 17:18
*/
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
5、consumer模块再新建controller包,将RestTemplate的bean引用:
package com.cobra.consumer.controller;
import com.cobra.consumer.client.ProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @Author: Baron
* @Description:
* @Date: Created in 2019/3/12 15:57
*/
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
/**
* 测试通讯
* @return
*/
@RequestMapping("/connect")
public String connect(){
//第一个provider为服务提供者的服务名称,如果要post请求,则需要组织参数
String result =restTemplate.getForObject("http://provider/provider/get", String.class);
return "connect to " + result;
}
}
6、启动eureka、consumer、和两个provider;我们会发现consumer对provider的请求是交替进行的,这是因为ribbon的负载均衡策略为轮询,如果需要改变负载均衡策略,需要在consumer上进行修改配置,例如改为随机模式:
provider:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
二、Feign通信:
1、在consumer模块的pom.xml加上依赖包
<!--使用feign添加依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、新建包client,新建接口,并给类加上注解@FeignClient(name = "provider"),指明name服务提供者,接口方法需要指明接口映射和请求方式。
package com.cobra.consumer.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
/**
* @Author: Baron
* @Description:
* @Date: Created in 2019/3/12 19:40
*/
@FeignClient(name = "provider")
public interface ProviderClient {
@GetMapping("/provider/get")
String get();
@PostMapping("/provider/post")
String post();
}
3、改造consumer的controller类
package com.cobra.consumer.controller;
import com.cobra.consumer.client.ProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @Author: Baron
* @Description:
* @Date: Created in 2019/3/12 15:57
*/
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private ProviderClient providerClient;
/**
* 测试通讯
* @return
*/
@RequestMapping("/connect")
public String connect(){
//String result =restTemplate.getForObject("http://provider/provider/get", String.class);
String get = providerClient.get();
String post = providerClient.post();
return "connect to " + get + post;
}
}
4、给启动类加上@EnableFeignClients注解:
package com.cobra.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
5、重启consumer,这时候eureka和provider均无变化,consumer对provider的请求依然正常,而且是随机的。如果删除掉ribbon的负载均衡策略,请求是交替的,说明Feign组件的负载均衡配置跟RestTemplate一样。
三、在正式开发中,Feign组件的使用,可以把client单独出来,打成jar包,供其他模块引用,引用的时候,需要在启动类添加对feignclient接口包的扫描。