12 服务间调用
微服务中,很多服务系统都在独立的进程中运行,通过各个服务系统之间的协作来实现一个大项目的所有业务功能。服务系统间 使用多种跨进程的方式进行通信协作,而RESTful风格的网络请求是最为常见的交互方式之一。
http。
思考:如果让我们写服务调用如何写。
- 硬编码。不好。ip域名写在代码中。目的:找到服务。
- 根据服务名,找相应的ip。目的:这样ip切换或者随便变化,对调用方没有影响。
Map<服务名,服务列表> map; - 加上负载均衡。目的:高可用。
spring cloud提供的方式:
- RestTemplate
- Feign
我个人习惯用RestTemplate,因为自由,方便调用别的第三方的http服务。feign也可以,更面向对象一些,更优雅一些,就是需要配置。
12.1 REST ful
RESTful网络请求是指RESTful风格的网络请求,其中REST是Resource Representational State Transfer的缩写,直接翻译即“资源表现层状态转移”。
Resource代表互联网资源。所谓“资源”是网络上的一个实体,或者说网上的一个具体信息。它可以是一段文本、一首歌曲、一种服务,可以使用一个URI指向它,每种“资源”对应一个URI。
Representational是“表现层”意思。“资源”是一种消息实体,它可以有多种外在的表现形式,我们把“资源”具体呈现出来的形式叫作它的“表现层”。比如说文本可以用TXT格式进行表现,也可以使用XML格式、JSON格式和二进制格式;视频可以用MP4格式表现,也可以用AVI格式表现。URI只代表资源的实体,不代表它的形式。它的具体表现形式,应该由HTTP请求的头信息Accept和Content-Type字段指定,这两个字段是对“表现层”的描述。
State Transfer是指“状态转移”。客户端访问服务的过程中必然涉及数据和状态的转化。如果客户端想要操作服务端资源,必须通过某种手段,让服务器端资源发生“状态转移”。而这种转化是建立在表现层之上的,所以被称为“表现层状态转移”。客户端通过使用HTTP协议中的四个动词来实现上述操作,它们分别是:获取资源的GET、新建或更新资源的POST、更新资源的PUT和删除资源的DELETE。
RestTemplate是Spring提供的同步HTTP网络客户端接口,它可以简化客户端与HTTP服务器之间的交互,并且它强制使用RESTful风格。它会处理HTTP连接和关闭,只需要使用者提供服务器的地址(URL)和模板参数。
反例:不对的。
上面概念虽说简单,如果面试被问到答错了,减分很厉害。有一个人说rest是和http并列的协议。
还有docker,说是医生(doctor),做云服务治理的,嘴里一堆高大上的词。
哲学家气质。
基础概念理解了,让人在心中给自己打个折,如果被某个大boss 在心中给打折了,有可能在这公司晋升都难。
12.2 调用
讲一下发送验证码逻辑。
{
"receivers": [
"13412341234","手机号"
],
"data": [
{
"id": "SMS_144145499",
"templateMap": {
"code": "9876"
}
}
]
}
为什么这么设计?
在当时业务初期用腾讯,后来换成了阿里,最后又加了华信。为了同时支持腾讯、阿里、华信等短信服务商。
例子:
- 启动eureka(为了方便用单节点:7900)。
- 启动service-sms,8002。
- yapi验证是否启动成功,接口能否访问。
- 验证是否注册到eureka。
- 用下面两种方式。
12.2 直接用RestTemplate调用
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// 正常 ribbon调用
ResponseEntity<ResponseResult> resultEntity = restTemplate.postForEntity(url, smsSendRequest, ResponseResult.class);
ResponseResult result = resultEntity.getBody();
启动api-driver。执行:yapi->api-driver 司机获取验证码。
12.3 feign调用
接口加注解,方法加注解
@FeignClient(name = "service-sms")
public interface SmsClient {
/**
* 按照短信模板发送验证码
* @param smsSendRequest
* @return
*/
@RequestMapping(value="/send/alisms-template", method = RequestMethod.POST)
public ResponseResult sendSms(@RequestBody SmsSendRequest smsSendRequest);
}
开启feign。
pom中feign。
启动api-driver。执行:yapi->api-passenger 发送验证码。