微服务实战之春云与刀客(二)—— Spring cloud 实现仿RPC面向接口调用方式-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

微服务实战之春云与刀客(二)—— Spring cloud 实现仿RPC面向接口调用方式

简介: 像HSF、dubbo这种RPC框架,客户端都是通过接口(Interface)调用服务的,无须自己拼装调用方式,客户端就像调用本地类方法一样。而spring cloud原生的客户端调用时通过RestTemplate发起Http调用请求,需要手动指定URL和参数,在使用上比较费劲,后来出现了申明式服务调用——Spring Cloud Feign,终于使调用得到了解放,而本文就是讲述如何极致地利用Feign来进行微服务开发。

概述

像HSF、dubbo这种RPC框架,客户端都是通过接口(Interface)调用服务的,无须自己拼装调用方式,客户端就像调用本地类方法一样。而spring cloud原生的客户端调用时通过RestTemplate发起Http调用请求,需要手动指定URL和参数,在使用上比较费劲,后来出现了申明式服务调用——Spring Cloud Feign,终于使调用得到了解放,而本文就是讲述如何极致地利用Feign来进行微服务开发,如何定义代码结构规范。

RestTemplate

RestTemplate 可以认为就是对HttpClient的一个封装,可以把调用的结果转化成Java 对象,从而达到简化开发的目的。
下面简单用一个例子来说明一下(例子实际设计到了eureka注册中心,关于如何使用eureka注册中心这些可以自己查阅相关资料,这里忽略)。在服务器端,我们像正常开发Controller一样写一个hi的方法,返回一个简单的字符串。
image

然后在客户端,显示需要注册一个RestTemplate Bean,这里@LoadBalanced的注解就是开启客户端负载均衡的能力(前提还需要在入口类上添加@EnableDiscoveryClient注解开启服务发现)
image

然后就像http请求一样调用服务器的hi方法,然后得到返回结果。例子中的equipment-service 是服务Id(serviceId),实际调用时会根据服务发现的结果替换成服务的ip和端口号。

image

可以看出,这种直接拼链接的调用对于微服务开发很不友好,所以才有了Feign的诞生。

申明式服务调用:Spring Cloud Feign

还是刚才的例子,在服务器端写个hi方法:
image

剩下的就是客户端的事情了。
首先,客户端需要引入Feign(这里也只是简要说一下流程)
image
然后定义一个interface。这个接口是什么意思呢?它实际就是把RestTemplate调用的链接转成了接口和方法。如URL中的equipment-service放到了interface的@FeignClient注解里面,而URL的路径对应方法上的@RequestMapping,URL参数也对应方法的参数,通过这种方式,巧妙地把URL调用转化成了方法的调用。
image

定义好接口后,Feign在spring初始化的时候会自动扫描包含@FeignClient的接口并注册成spring bean,然后就可以直接使用了
image

Feign 的接口定义移到服务器端

上面的代码接口是在客户端定义的,无形中客户端多了这一块麻烦的工作,而比较合理的做法是由服务提供者来提供接口。
首先在服务端定义接口
image

然后服务器端新建一个Controller(注意是Controller)继承这个接口。
image

最后客户端只需引入这个接口,就像本地spring bean一样调用服务了,客户端是不用关系服务在哪台服务上面的。

image

微服务代码结构规范

在上面接口调用的基础上,我们可以总结出一套代码结构规范。

image

1、首先所有的微服务有一个根级的root pom,包含了spring cloud的版本等基本定义信息,同时也定义好统一的groupId。这个pom文件最大的好处就是统一了spring
cloud的版本,避免以后开发中出现的各种不兼容问题。
这个pom定义好后一般不轻易改变,如果接入新版本的spring cloud,则升级maven version再deploy到maven服务器即可。

<parent>
    <groupId>com.cehome.cloud</groupId>
    <artifactId>cehome-cloud-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</parent>

2、和root pom同目录下是各种微服务目录(项目),每种微服务为一个项目,每个项目下面再分为api(接口)和service(实现)模块。

3.一个服务开发的流程是这样的:
服务器端:在api模块定义服务接口,在service模块实现服务。
客户端:直接依赖api jar包即可调用服务,无须了解调用服务器地址和具体的URL。

例如对于user微服务,服务器端由user-api 和user-service两个模块,开发完后,user-api发布到maven服务器成user-api-1.0.0.jar;
客户端直接依赖user-api-1.0.0.jar,引用服务接口就可以调用服务。
注意user-api-1.0.0.jar是一个非常轻量级的jar包,只包含了interface和一些实体类定义,一般不会有微服务实现的代码逻辑。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章