(二)springCloud 服务间的通信方式

在说这两种方式之前,先来简单的了解一下Ribbon。(之后学习总结)

简单的说Ribbon是一个负载均衡客户端,SpringCloud的两种服务间调用方式背后都用了Ribbon。

一、springCloud 服务间的通信方式有两种

  • RestTemplate 方式

  • Feign 的方式

不管是什么方式,他都是通过REST接口调用服务的http接口,参数和结果默认都是通过jackson序列化和反序列化。

二、使用RestTemplate方式

代码demo接:https://blog.csdn.net/o_darling/article/details/82021616

1. 首先启动springcloud-eureka工程(注册中心),把SpringCloud的服务注册中心启动。

2.在工程springcloud-common(作为服务端)中写一个提供服务的方法

/**
 * 
 * @Title: ServerController.java
 * @Package com.common.controller
 * @Description: TODO(用一句话描述该文件做什么)
 * @author FayQ
 * @date 2018年7月6日
 * @version V1.0
 * @email 1010046660@qq.com
 */
@RestController
@RequestMapping(value="/common")
public class ServerController {

	@Value("${server.port}")
    private String port;

    @GetMapping("/hello")
    public String hello() {
        return "Hello! I'm server:" + port;
    }
    
}

3.在项目springcloud-common-api中(作为客户端);编写客户端,有三种方式调用方法,如下:

package com.common.consumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * 
 * @Title: ClientController.java
 * @Package com.common.controller
 * @Description: TODO(用一句话描述该文件做什么)
 * @author FayQ
 * @date 2018年7月6日
 * @version V1.0
 * @email 1010046660@qq.com
 */
@RestController
@RequestMapping(value="/client")
public class ClientController {

	@Autowired
    private RestTemplate restTemplate;
	
	@Autowired
    private LoadBalancerClient loadBalancerClient;
	
	@Value("${server.port}")
    private String port;
	
	@GetMapping("/helloClient")
    public String helloClient() {
        return "Hello! I'm client:	" + port;
    }
	/**
	 * 第一种方式:直接使用 RestTemplate ,url 写死;
	 * 因为服务端的 api 被硬编码在客户端,因此有两个缺点: 
	 * – 当注册中心有很多服务时,我们可能不知道我们需要的服务由谁提供、api是多少,因此就可能无法调用到服务。 
	 * –当某个服务部署了多个,例如 api 是: “localhost:8080/hello,localhost:8081/hello “,那么此时就需要负载均衡,这种硬编码显然不符合场景。
	 */
	@GetMapping("/helloServer1")
    public String helloServer1() {
		RestTemplate rt = new RestTemplate();
        return rt.getForObject("http://192.168.126.31:8001/common/hello", String.class);
    }
	/**
	 * 第二种方式:客户端通过 LoadBalancerClient 来获取应用名,进而获取地址和端口,在格式化拼接地址,从而调用 product服务。
	 * 缺点是每次调用服务都要这样写,编码很麻烦。
	 */
	@GetMapping("/helloServer2")
    public String helloServer2() {
    	
		RestTemplate restTemplate = new RestTemplate();
        ServiceInstance serviceInstance = loadBalancerClient.choose("spring-cloud-common");  // serviceId 为提供服务的应用名
        String url = String.format("http://%s:%s",serviceInstance.getHost(),serviceInstance.getPort() + "/common/hello");
        String response = restTemplate.getForObject( url, String.class);
        return response;
    }
	/**
	 * 第三种方式:通过 @LoadBalanced,可在restTemplate 直接使用应用名字。
	 */
	@GetMapping("/helloServer3")
    public String helloServer3() {
    	
        return restTemplate.getForObject("http://spring-cloud-common/common/hello", String.class);
    }
}

其中第三种方法需要:

@Configuration
public class ConfigBeans {

	@Bean
	@LoadBalanced
	public RestTemplate restTemplate(){
		return new RestTemplate();
	}
}

测试结果如下:

二、使用Feign方式

1. 添加依赖jar

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2.启动类添加@EnableFeignClients注解

@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient //Eureka Client
public class AppMain {
    public static void main(String[] args) {
//        new SpringApplicationBuilder(AppMain.class).web(true).run(args);
        SpringApplication.run(AppMain.class, args);
    }
}

3. 定义一个Feign接口 

package com.common.consumer.service;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "spring-cloud-common")  // 服务名
public interface ServerService {

	@GetMapping("/server/hello")// 这里要和 Product服务提供的接口一致
	String hello();
}

4.在配置了Feign接口后,我们就可以直接进行注入调用了

package com.common.consumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.common.consumer.service.ServerService;

@RestController
@RequestMapping(value="/feignclient")
public class FeignClientController {

	@Autowired
	private ServerService service;
	
	@GetMapping("/feignHello")
    public String feignHello() {
        return service.hello();
    }
}

测试:

 

 

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值