SpringCloud-同步调用

SpringCloud文章系列

  1. SpringCloud
  2. SpringCloud-注册中心
  3. SpringCloud-配置中心
  4. SpringCloud-链路跟踪
  5. SpringCloud-消息总线
  6. SpringCloud-API网关
  7. SpringCloud-异步消息
  8. 【当前文章】SpringCloud-同步调用
  9. SpringCloud-断路降级
  10. SpringCloud-监控管理
  11. SpringCloud-番外篇-临时任务
  12. SpringCloud-番外篇-文档生成
  13. SpringCloud-番外篇-源码解析

接入说明

  1. 目前采用最新的1.xRelease版本:1.5.15.RELEASE
  2. SpringCloud项目可以在start.spring.io下载,不过更方便的应该是通过idea新建项目,建立Spring Initializr项目
  3. 我一般习惯将具体实现服务用具体的服务名,而公共组件用service-xxx来命名,当然还有一些比较固定名字的公共组件
  4. 基于配置中心,请先按照配置中心章节,配置公共配置
  5. 依赖链路追踪章节

同步调用

同步调用主要是通过HTTP去请求的,这里演示Feign的调用,重点在客户端的实现,服务端暴露接口就是普通的SpringMVC的使用

1. 新建项目

继续使用”异步调用”章节的artifactId为account-service的服务

2. 导入依赖

依赖说明

  1. 可以显示引入web的依赖
  2. actuator与eureka-server已经依赖web,其实SC中大部分组件已经强依赖web了,依赖这些组件可以不显示依赖(不过建议还是明确引入)
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

3. 编写服务端暴露接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RefreshScope
@RestController
class MessageController {

private final String msg;

@Autowired
public MessageController(@Value("${message}") String msg){
this.msg = msg;
}

@RequestMapping("/msg")
public String read() {
return msg;
}

}

这个接口还是使用配置中心章节使用的/msg接口暴露服务

4. 启动main

5. 验证

访问http://localhost:8020/msg 可以返回配置中心的msg配置数据

客户端使用

客户端使用项目business-service演示

1. 添加依赖

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

2. 开启注解

BusinessServiceApplication上加入@EnableFeignClients开启Feign

3. 添加调用代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@FeignClient("account-service")
interface AccountRead {

@RequestMapping(method = RequestMethod.GET, value = "/msg")
String read();

}

@RestController
class AccountController {

@Autowired
private AccountRead accountRead;

@RequestMapping("/account-msg")
public String read() {
return accountRead.read();
}
}

之前在account-service中声明的/msg接口在这里使用同样的SpringMVC的注解标注AccountRead接口接口代表远程调用的客户端
然后调用时只需要@Autowired注入即可使用

其他同步调用方式

如restfulTemplate也可以远程调用,不过不如feign方便,需要拼请求参数的URL,当前例子因为不需要拼接参数,所以看起来差不多

快速接入

在main类或者config类中构建一个RestTemplate,标记@LoadBalanced,则会采用Ribbon提供的负载均衡算法

1
2
3
4
5
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
public class AccountController2 {

@Autowired
private RestTemplate restTemplate;

@RequestMapping("/account-msg")
public String read(){
return restTemplate.getForObject("http://account-service/msg", String.class);
}

}

疑问

如果返回的不是String,而是一个对象呢?

对象只需要在客户端这里声明一个类似的对象即可自动转换,其实中间数据都是用json传输的,类名可以不一样,只要属性一样即可匹配

请求调用的IP与端口号我想获取或者单独控制怎么实现?

Feign其实是依赖Ribbon去做负载均衡的,可以在配置中配置负载均衡策略
具体获取请求IP与端口控制可以直接使用Ribbon去请求可以获取到负载的IP与端口号,结合RestfulTempldate去请求服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController
class AccountController {

@Autowired
private LoadBalancerClient client;
@Autowired
private RestTemplate restTemplate;

@RequestMapping("/account-msg2")
public String read2() {
ServiceInstance serviceInstance = client.choose("account-service");
String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/msg";
return restTemplate.getForObject(url, String.class);
}

}
------ 本文结束 ------

版权声明

dawell's Notes by Dawell is licensed under a Creative Commons BY-NC-ND 4.0 International License.
Dawell创作并维护的dawell's Notes博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证
本文首发于dawell's Notes 博客( http://dawell.cc ),版权所有,侵权必究。

坚持原创技术分享,您的支持将鼓励我继续创作!