公司的几个核心应用采用restful风格的服务接口对外提供服务,这些应用均采用Java spring mvc来实现rest服务,调用这些服务的消费者应用使用的语言则有多种,主要有php、python、Ruby、Java、C++、C#。
随着服务接口数量和消费者应用的增多,需要有一个rest服务治理框架来进行支撑,该服务治理框架提供的功能主要有:
服务注册和发现
负载均衡与容错
服务授权和鉴权
服务依赖关系管理
服务性能采集和监控
借鉴阿里dubbo框架,设计了公司的http api服务治理框架,整个架构如下。
采用zookeeper作为服务注册中心,服务提供者(上图右边所示的java rest服务应用)将服务发布注册到zookeeper中,服务消费者(上图左边所示的client应用)根据服务名和版本等限定参数查找对应的服务,获取服务endpoint url列表。在endpoint url列表有变动时,通过zookeeper的watch机制将变动推送到服务消费者。
服务控制中心是一个web控制台,提供的功能主要有:
管理应用(服务提供者、服务消费者应用):每个应用都有一个应用id和应用密钥以及应用负责人等信息。
应用信息同时要写到zookeeper上。
展示服务依赖关系的全局视图(每个应用提供有哪些服务,这些服务被哪些消费应用依赖)、
服务访问授权和鉴权:控制每个服务可被哪些消费者应用调用,支持应用白名单和黑名单以及客户端ip地址授权。服务调用时的鉴权:授权信息要写到zookeeper上,然后推送到服务提供者应用以便进行服务鉴权。
展示服务的部署信息:服务地址endpoint、健康状况、调用性能等运行信息。
服务生命周期管理
服务发布
对Java spring mvc实现的rest服务,要发布服务,需要3处修改:
1)在spring dispatch servlet对应的bean配置文件中加入定制标签,增加内容如下:
<!-- 加入spring定制名称空间yyservice -->
<beans ... xmlns:yyservice="http://code.duowantech.com/schema/yyservice"
xsi:schemaLocation="http://code.duowantech.com/schema/yyservice http://code.duowantech.com/schema/yyservice/yyservice.xsd"
...><yyservice:application name="xxx-webservice" version="1.0"/>
<yyservice:serviceRegistry name="zk1" address="58.249.117.107:2181"/>
<yyservice:restServiceExporter appEndpoint="*:8080" context="" urlPattern="/api/*"/>
...
</beans>
yyservice:application指定应用名称和应用版本;yyservice:serviceRegistry指定zookeeper的
连接字符串(ip:端口);yyservice:restServiceExporter用来将spring mvc rest服务注册到zookeeper,appEndpoint表示应用的ip和http端口,context是servletContext名称,对root servletContext,context为""。urlPattern是spring dispatch servlet对应的url pattern,要和web.xml中的url pattern保持一致。
2)在服务提供者应用的pom文件中加入治理框架提供的1个jar包依赖。这个jar包实现了上面的定制名称空间yyservice,同时提供spring mvc intercept来进行客户端调用鉴权和调用性能采集、服务健康监控接口等。
3)这步是可选的。在spring mvc controller类(就是它实现了rest服务)中加入框架提供的注解信息。
//ServerResource.java
@Controller
@RequestMapping(value="/servers")
@ResourceDesc(name = "ServerResource",desc="服务器资源")
public class ServerResource {
...
@MethodDesc(desc="根据server id查找服务器")
@RequestMapping(value = "/id-{serverId}",method=RequestMethod.GET)
@ResponseBody
public Result<Server> findServer(@PathVariable Integer serverId) {
...
}
@MethodDesc(desc="创建服务器")
@RequestMapping(method=RequestMethod.POST)
@ResponseBody
// serialNo流水号唯一,防止失败重试时重复重建
public Result<CreateResult> createServer(String serialNo,Server server) {
...
}
@MethodDesc(desc="更新服务器")
@RequestMapping(value = "/id-{serverId}",method=RequestMethod.PUT)
@ResponseBody
public Result<DeleteResult> updateServer(@PathVariable Integer serverId,Server server) {
...
}
@MethodDesc(desc="删除服务器")
@RequestMapping(value = "/id-{serverId}",method=RequestMethod.DELETE)
@ResponseBody
public Result<DeleteResult> delServer(@PathVariable Integer serverId) {
...
}
}
上图中的ServerResource类(该类表示服务器rest资源)中,ResourceDesc和MethodDesc注解是治理框架提供的,承载资源的描述信息,这两个注解是可选的,根据需要添加,其他注解是spring mvc的。每种类型的rest 资源都有一个唯一的资源名称,缺省情况下,资源名称是java类的全限定名(含包名),如果ResourceDesc的name属性不为空,则使用该名称作为资源名。ResourceDesc和MethodDesc中的信息会展示在服务控制中心的展示页面中。
通过三面的3步,服务应用启动后会自动将服务注册到注册中心,ResourceDesc和MethodDesc注解中的信息也会自动添加到数据库中,最终展示在服务控制中心的展示页面中。
如果rest服务不是采用spring mvc实现或非java应用(如python应用)提供的rest服务,需要提供一个服务信息xml文件,在这些应用代码中调用框架提供的服务注册api,将这个xml文件传给api的注册方法即可将服务注册到zookeeper。
服务发现和服务调用
java应用调用rest服务,步骤如下
1)spring bean配置文件中加入如下的定制标签
<beans ... xmlns:yyservice="http://code.duowantech.com/schema/yyservice"
xsi:schemaLocation="
...
http://code.duowantech.com/schema/yyservice http://code.duowantech.com/schema/yyservice/yyservice.xsd ..."
>
...
<yyservice:application name="dcm" version="1.0"/>
<yyservice:serviceRegistry name="zk1" address="58.249.117.107:2181"/>
<yyservice:restServiceReference id="serverResource" resourceName="ServerResource" connTimeout="1000" readTimeout="3000"
/>
yyservice:application和yyservice:serviceRegistry标签先前已有介绍。
yyservice:restServiceReference标签会生成一个rest客户端bean(其类型是RestServiceClient,父类是spring中的RestTemplate类 ),resourceName为ServerResource,表示该客户端bean可用来调用前面提到的ServerResource中的服务。
2)和服务提供者应用相同,在消费者应用的pom文件中加入治理框架提供的1个jar包依赖。
3)在需要调用这个ServerResource资源服务的其他bean中注入该客户端bean。
其他bean可通过bean配置文件中的ref属性(其值为restServiceReference标签中的id值serverResource)来引用该bean,或在类中使用Resource注解来自动注入,例如:
//import javax.annotation.Resource;
@Resource(name="serverResource")
private RestTemplate serverResourceClient;
//或private RestServiceClient serverResourceClient;
调用接口文档见spring的RestTemplate类。例如要调用serverResource中的删除服务器,使用
serverResourceClient.delete("/servers/id-1234"); //删除server id为1234的服务器。
唯一需要注意的地方是url中只要提供spring mvc controller(rest资源)RequestMapping注解中的url即可,
不需要要写完整的url,例如上面的delete方法中传的是/server/id-1234,没有http://ip:端口、serverletContext和urlPattern,这些ip、端口等都是和部署相关的信息,编写客户端调用代码时不需要关心这些。serverResourceClient会从服务注册中心根据资源名称找到这些信息(服务发现),然后拼接成完整的url发起调用。如果有多个ip和端口提供服务,会采用轮询机制选取一个发起调用(服务负载均衡)。
非java应用调用rest服务
对非java应用,用c++编写了调用客户端(linux下yyhttpserviceclient.so和windows下yyhttpserviceclient.dll),c++客户端可使用该客户端来调用rest服务。该客户端调用模型如下:
c++调用实例如下:
/*调用instance静态方法返回单例资源工厂*/
YyHttpResourceFactory* resourceFactory = YyHttpResourceFactory::instance( );
/*只需初始化一次,参数分别是appId,zookeeper链接串、应用版本*/
resourceFactory->init("myappId","58.249.117.107:2181","1.0");
/*调用资源工厂的resource方法返回http服务(资源)指针,该对象可重用。*/
YyHttpResource* pServerResource = resourceFactory->resource("serverResource");
/*创建该资源下的请求*/
YyHttpRequest* req = pServerResource->url("/servers/id-1234");
//和java RestTamplate相同,也可使用url模板来设置url中的参数,如下:
/*
std::map<std::string,std:string> paraMap;
map.insert(make_pair("serverId","1234"));
YyHttpRequest* req = pServerResource->url("/servers/id-{serverId}",paraMap);
*/
/*设置查询参数、http头、请求body、失败重试次数、链接和读超时时间等
// req->appendQueryString("参数名","参数值")-> appendHeader("http头名称","值")->body("...")->retries(2)
//调用delete方法发送http请求,返回应答resp*/
YyHttpResponse* resp = req->delete();
/*是否有网络错误*/
resp->isNetworkError( );
/*获取网络错误码*/
resp->getErrorNo( );
/*没有网络错误,查看http状态码*/
resp->getStatusCode( );
/*http应答body*/
resp->getResponseBody( );
/*body的content type*/
resp->getContentType( );
/*req、resp为一次性对象,不能重复使用。释放资源,否则会有内存泄漏*/
req->release( );
resp->release( )
对除Java和C++之外的语言,如python、php、ruby、C#等调用rest服务,框架使用swig来支持多语言客户端。swig是个可将C或者C++编写的代码变成能与其它各种高级编程语言进行嵌入联接的开发工具。采用swig后,可以通过c++客户端自动生成python、php等使用的客户端。例如将前面的c++客户端代码经过swig处理后可编译生成python调用的_yyhttpserviceclient.so和yyhttpserviceclient.py。在这些语言中的调用过程和c++客户端相同,均遵从相同的调用模型和方法。在python中删除服务器资源示例如下:
import yyhttpserviceclient
yyHttpResourceFactory = yyhttpserviceclient.YyHttpResourceFactory.instance( )
yyHttpResourceFactory.init('dcm','58.249.117.107:2181','1.0')
resource = yyHttpResourceFactory.resource('serverResource')
req = resource.url('/servers/id-1234')
//req.appendHeader('x','1').appendHeader('y','2')
//返回response
resp = req.delete()
resp.getResponseBody( )
resp.release( )
req.release( )
相关推荐
Kepler的角色分工Service/Client:服务提供者/服务调用者Registry:注册中心@See[Monitor]:数据收集服务, 收集服务运行时状态@See[Admin]:服务管理中心, 提供服务治理统一入口(API) 标签:Kepler
能够实现热服务编排,自动授权选择,在线服务脚本编码,在线测试,高性能路由,API审核管理等目的,拥有强大的自定义插件系统可以自行扩展,并提供友好的图形化配置界面,能够快速帮助企业进行API服务治理,减少中间...
Dubbo 是一个分布式、高性能、透明化的 RPC 服务框架,提供服务自动注册、自动发现等高效服务治理方案, 可以和 Spring 框架无缝集成。 RPC 指的是远程调用协议,也就是说两个服务器交互数据。 2.Dubbo的由来? ...
Boot框架和Protocol Buffers实现了高效的微服务开发框架,它支持服务定义、服 务注册发现、服务间REST和RPC通信、服务持续集成等功能。另外,结合Nginx 和Lua语言的OpenResty平台,开发了具有权限校验、流量控制、...
分为API层、服务实体层、服务调用层、服务实现层、服务基础层,包含代码生成、认证授权、菜单管理、角色管理、用户管理、字典管理、日志管理、个人资料、密码修改、商品管理、We`Chat通用模块、服务发现与配置监控、...
没有繁琐的 yield, 有类似 Go 语言的协程、灵活的注解、强大的全局依赖注入容器、完善的服务治理、灵活强大的 AOP、标准的 PSR 规范实现等等,可以用于构建高性能的Web系统、API、中间件、基础服务等等。 暂无标签
轻松获得支撑千万日活服务的稳定性,内建级联超时控制、限流、自适应熔断、自适应降载等微服务治理能力,无需配置和额外代码,微服务治理中间件可无缝集成到其它现有框架使用,极简的 API 描述,一键生成各端代码,...
没有繁琐的 yield, 有类似 Go 语言的协程、灵活的注解、强大的全局依赖注入容器、完善的服务治理、灵活强大的 AOP、标准的 PSR 规范实现等等,可以用于构建高性能的Web系统、API、中间件、基础服务等等。
没有复杂的异步回调,没有繁琐的 yield 有类似 Go 语言的协程、灵活的注解、强大的全局依赖注入容器、完善的服务治理、灵活强大的 AOP、标准的 PSR 规范实现等等,可以用于构建高性能的Web系统、API、中间件、基础...
没有繁琐的 yield, 有类似 Go 语言的协程、灵活的注解、强大的全局依赖注入容器、完善的服务治理、灵活强大的 AOP、标准的 PSR 规范实现等等,可以用于构建高性能的Web系统、API、中间件、基础服务等等。
没有复杂的异步回调,没有繁琐的 yield,有类似 Go 语言的协程、灵活的注解、强大的全局依赖注入容器、完善的服务治理、灵活强大的 AOP、标准的 PSR 规范实现等等,可以用于构建高性能的Web系统、API、中间件、基础...
Dubbo Admin之前的版本过于老旧,也长期疏于维护,因此在去年年中的时候,对该项目进行了...当前版本的Dubbo Admin包含了之前版本中的绝大部分功能,包括服务治理,服务查询等,同时支持了Dubbo2.7中服务治理的新特性。
以常见电商微服务为模型,本工程是自建微服务系统核心架构,利用Zookeeper做服务治理,用Hystrix做服务容错保护。 工程中业务代码没有编写,但是详细的框架代码都已经全部编写完成,况且有非常详细的注释与说明,并...
基于swoole一款高性能多进程常驻内存型全栈框架,内置WebSocket服务器、服务治理PhpRpc功能,不依赖传统的 PHP-FPM,可以用于构建高性能的Web系统、API、中间件、基础服务等等。 软件开发设计:PHP、应用软件开发、...
合理的分布式服务划分(common+api+service+web) 资源调度和治理中心(SOA)(dubbo-admin) 服务监控方案(dubbo-monitor) <项目介绍> 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩...
API-Builder 社区插件是一个非常灵活的低代码无代码框架,可帮助客户通过以下方式为 API 管理治理层创建或优化 API: 将记录 API 的系统编排为面向业务的 API 连接到不同的云或本地应用程序在几分钟内连接到数据库以...
基于微信小程序的消防隐患在线举报...通过以上功能的设计与实现,基于微信小程序的消防隐患在线举报系统结合SSM框架为社区居民和相关部门提供了一个便捷、高效的沟通平台,有助于提升消防安全管理水平和社区治理效能。
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。 其核心部分包含: 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-...
服务治理SpringCloud Eureka 5 什么是服务治理 5 服务注册与发现 5 搭建注册中心 6 常用注册中心框架 6 注册中心环境搭建 6 注册服务提供者 8 服务消费者 11 高可用注册中心 14 Eureka高可用原理 14 ...