前言:

  • 在springcloud微服务的实际项目开发中,多个微服务之间不仅是相对独立的,而且也是相对关联的;也就是说,微服务之间需要相互访问,多个微服务之间的接口可能会被互相多次调用,我们称之为微服务之间的通信
  • 微服务之间的通信方式有很多,一般使用以下两种方法:一种是RestTemplate,另一种是Feign;

概念简介:

  • RestTemplate,是spring中方便使用rest资源的一个对象,交互访问的资源通过URL进行识别和定位,每次调用都使用模板方法的设计模式,模板方法依赖于具体接口的调用,从而实现了资源的交互和调用;  它的交互方法有30多种,大多数都是基于HTTP的方法,比如:delete()、getForEntity()、getForObject()、put()、headForHeaders()等; 
  •  Feign,一个声明式的伪HTTP客户端,使得编写HTTP客户端更加容易;    它只需要创建一个接口,并且使用注解的方式去配置,即可完成对服务提供方的接口绑定,大大简化了代码的开发量;     同时,它还具有可拔插的注解特性,而且支持feign自定义的注解和springMvc的注解(默认);

注意事项:

RestTemplateFeign两种通信方式发现不可共用,原因未知,有了解的程序猿不吝赐教!

RestTemplate代码实践:

  •  搭建eureka服务注册中心环境(这里不做描述,可自行搭建;
  • 添加依赖;
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • 在启动类Application添加负载均衡标识;
@LoadBalanced
@Bean
public RestTemplate getRestTemplate() {
	return new RestTemplate();
}
  • 服务提供类,服务名称:SERVICE1,端口:8082;
@RestController
@RequestMapping("/service1")
public class TestController {
		
	@RequestMapping(value = "test", method = {RequestMethod.POST,RequestMethod.GET})
	public String test(@RequestParam(value = "testParam") String testParam) {
		System.println.out(testParam);
		return "success";
	}
		
}
  • 服务消费类;
@RestController
@RequestMapping("/serviceFront")
public class ServiceFrontController {

	private final static String SERVICE1_URL = "http://SERVICE1:8082";

	private final static String SERVICE1 = "SERVICE1";

	@Autowired	
	LoadBalancerClient loadBalancerClient;

	@Autowired
	RestTemplate restTemplate;

	@RequestMapping(value = "testFront", method = RequestMethod.POST)
	public HashMap<String,Object> testFront(@RequestParam String testParam) {
		this.loadBalancerClient.choose(SERVICE1);// 随机访问策略
		String result = restTemplate.getForObject(SERVICE1_URL + "/service1/test?testParam={1}", String.class, testParam);
		HashMap<String,Object> map = new HashMap<String,Object>();
		map.put("result", "测试结果!"+result);
		return map;
	}
}

Feign代码实践:

  •  搭建eureka服务注册中心环境(这里不做描述,可自行搭建);
  • 添加依赖;
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
  • 在启动类Application添加feign注解,声明启动feign客户端;
@EnableFeignClients
  • 服务提供类,服务名称:SERVICE2,端口:8083;
@RestController
@RequestMapping("/service2")
public class TestController2 {
	
	@RequestMapping(value = "test2", method = {RequestMethod.POST,RequestMethod.GET})
	public String test2(@RequestParam(value = "testParam2") String testParam2) {
		System.println.out(testParam2);
		return "success";
	}
	
}
  • 服务消费接口类;
/**
 * 封装调用服务接口
 */
@FeignClient(name = "SERVICE2")
public interface TestFeignClient {

	//@RequestLine("GET /service2/test2")
	@RequestMapping(value="/service2/test2",method = RequestMethod.GET)
	public String test2(@RequestParam("testParam2") String testParam2);
		
}
  • 服务消费控制层;
@RestController
@RefreshScope
@RequestMapping("/serviceFront2")
public class TestFeignController {
	
	@Autowired
	private TestFeignClient testFeignClient;

	@RequestMapping(value = "test2", method = { RequestMethod.POST })
	public HashMap<String,Object> test2(@RequestParam String testParam2) {		
		String result = testFeignClient.test2(testParam2);
		HashMap<String,Object> map = new HashMap<String,Object>();
		map.put("result", "测试结果!"+result);
		return map;
	}
}

总结:

微服务之间的通讯方式可以多种并存,各有优势,在项目实践中可具体情况具体分析,程序猿可以在开发系统的过程中,积累总结封装通讯的最佳方式,开发效率事半功倍~

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐