lms框架应用服务接口和服务条目详解
应用接口的定义
服务应用接口是微服务定义webAPI的基本单位,可以被其他微服务应用引用,其他微服务可以通过rpc通信与该微服务进行通信。应用接口如果被网关应用引用,网关可以通过服务应用接口生成swagger文档。
通过ServiceRouteAttribute特性对一个接口进行标识即可成为一个服务应用接口。
例如:
[ServiceRoute]
public interface ITestAppService
{
}
服务路由特性
开发者对应用接口标识路由(ServiceRouteAttribute)时,可以通过路由特性的属性对生成的路由模板、应用接口请求头是否支持serviceKey进行配置。
| 属性名称 | 说明 | 缺省值 |
|---|---|---|
| template | 在对服务应用接口标识为服务路由时,可以通过[ServiceRoute(template: "test/{appservice=templateName}")]指定应用服务接口的路由模板。 |
api/{appservice} |
| multipleServiceKey | 网关生成的webapi请求头是否支持serviceKey请求头 |
false |
服务条目
服务条目(ServiceEntry): 服务应用接口中定义的每一个方法都会生成微服务集群的一个服务条目。对微服务应用本身而言,服务条目就相当于MVC中的Action,服务应用接口就相当于Controller。
根据服务条目生成webAPI
应用接口被网关引用后,会根据服务应用接口的路由模板和服务条目方法的Http动词特性指定的路由信息或是方法名称生成相应的webapi,服务条目生成的WebAPI支持restfulAPI风格。
服务条目生成webapi的规则为:
禁止集群外部访问的服务条目(
[Governance(ProhibitExtranet = true)])不会生成webapi;可以通过
[ServiceRoute(template: "test/{appservice=templateName}")]为应用接口指定统一的路由模板;如果服务条目方法没有被http谓词特性标识,那么生成的webapi的http请求动词会根据服务条目的方法名称生成,如果没有匹配到相应的服务条目方法,则会根据服务条目的方法参数;
服务条目方法可以通过http谓词特性进行标识,并且http谓词特性还支持对服务条目指定路由模板,路由模板的指定还支持对路由参数进行约束;
服务条目生成的webAPI = 应用接口条目路由模板 + “方法名称||Http特性指定的路由特性”
如果不存在Http谓词特性标识情况下,生成的webapi路由说明(例如,应用接口名称为:ITestAppService,路由模板未被改写):
| 方法名称 | 生成的webAPI路径 | Http请求动词 |
|---|---|---|
| GetXXX | /api/test | get |
| SearchXXX | /api/test/search | get |
| CreateXXX | /api/test | post |
| UpdateXXX | /api/test | put |
| DeleteXXX | /api/test | delete |
存在Http谓词情况下,生成的webapi的请求动词会根据服务条目标识的http谓词特性来决定,开发者还可以通过http谓词特性为服务条目的的路由进行调整,并且支持路由参数的形式,例如:
| 方法名称 | 生成的webAPI路径 | http谓词特性 | Http请求动词 |
|---|---|---|---|
| GetXXX | /api/test/{id} | [HttpGet("{id:strig}")] | get |
| DeleteXXX | /api/test/name/{name} | [HttpDelete("name/{name:strig}")] | delete |
| UpdateXXX | /api/test/email | [HttpPatch("email")] | patch |
| CreateXXX | /api/test/user | [HttpPost("user")] | post |
服务条目的治理特性
开发者可以通过配置文件对服务条目的治理进行统一配置,除此之外可以通过Governance特性为服务条目方法进行标识,通过其属性对服务条目进行治理。通过Governance特性对服务条目方法注解后,服务条目的治理属性将会被该特性重写。
服务条目治理的属性请参考服务条目治理属性配置。
缓存拦截
在服务应用接口被其他微服务应用引用后,可以通过缓存拦截特性(GetCachingIntercept)在rpc通信过程中,直接从分布式缓存中读取数据,避免通过网络通信,而从提高系统性能。
更多关于缓存拦截请参考缓存拦截。
服务条目的例子
[ServiceRoute]
public interface ITestAppService
{
/// 新增接口测试([post]/api/test)
[GetCachingIntercept("name:{0}")]
Task<TestOut> Create(TestInput input);
/// 更新接口测试([put]/api/test)
Task<string> Update(TestInput input);
/// 删除接口测试([delete]/api/test)
[RemoveCachingIntercept("ITestApplication.Test.Dtos.TestOut", "name:{0}")]
[Transaction]
Task<string> Delete([CacheKey(0)] string name);
/// 查询接口测试([get]/api/test/search)
[HttpGet]
Task<string> Search([FromQuery] TestInput query);
/// 以表单格式提交数据([post]/api/test/form)
[HttpPost]
string Form([FromForm] TestInput query);
/// 通过name获取单条数据([get]/api/test/{name:string},以path参数传参,并约束参数类型为string)
[HttpGet("{name:string}")]
[Governance(ShuntStrategy = AddressSelectorMode.HashAlgorithm)]
[GetCachingIntercept("name:{0}")]
Task<TestOut> Get([HashKey] [CacheKey(0)] string name);
/// 通过id获取单条数据([get]/api/test/{id:long},以path参数传参,并约束参数类型为long)
[HttpGet("{id:long}")]
[Governance(ShuntStrategy = AddressSelectorMode.HashAlgorithm)]
[GetCachingIntercept("id:{0}")]
Task<TestOut> GetById([HashKey] [CacheKey(0)] long id);
///更新部分数据,使用patch请求 ([patch]/api/test)
[HttpPatch]
[Governance(FallBackType = typeof(UpdatePartFallBack))]
Task<string> UpdatePart(TestInput input);
}
应用接口的实现
一般地,开发者应当将应用服务接口和应用服务接口的实现分开定义在不同的程序集。应用接口程序集可以被打包成Nuget包或是以项目的形式被其他微服务应用引用,这样其他微服务就可以通过rpc代理的方式与该微服务应用进行通信。更多RPC通信方面的文档请参考。
一个应用接口可以有一个或多个实现类。只有应用接口在当前微服务应用中存在实现类,该微服务应用接口对应的服务条目才会生成相应的服务路由,并将服务路由信息注册到服务注册中心,同时其他微服务应用的实例会订阅到微服务集群的路由信息。
如果服务应用接口存在多个实现类,那么服务应用接口的路由特性应的multipleServiceKey的参数值应当被设置为true([ServiceRoute(multipleServiceKey: true)])。这样,在网关应用引用该微服务的应用接口程序集生成的swagger文档才会有serviceKey请求头。
应用接口如果存在多个实现类的情况下,那么应用接口的实现类,需要通过ServiceKeyAttribute特性进行标识。ServiceKeyAttribute存在两个参数(属性)。
| 属性名称 | 说明 | 备注 |
|---|---|---|
| name | 服务实现类的名称 | 通过webapi请求时,通过请求头serviceKey进行设置;rpc通信中,可以通过ICurrentServiceKey的实例调整要请求的应用接口实现。 |
| weight | 权重 | 如果通信过程中,未指定serviceKey,那么,会请求权重最高的应用接口的实现类 |
实例:
/// 应用服务接口(如:可定义在ITestApplication.csproj项目)
[ServiceRoute(multipleServiceKey: true)]
public interface ITestAppService
{
Task<string> Create(TestInput input);
// 其他服务条目方法略
}
//------------------------------------//
/// 应用服务实例类1 (如:可定义在TestApplication.csproj项目)
[ServiceKey("v1", 3)]
public class TestAppService : ITestAppService
{
public Task<string> Create(TestInput input)
{
return Task.FromResult("create v1")
}
// 其他接口实现方法略
}
//------------------------------------//
/// 应用服务实例类2 (如:可定义在TestApplication.csproj项目)
[ServiceKey("v2", 1)]
public class TestV2AppService : ITestAppService
{
public Task<string> Create(TestInput input)
{
return Task.FromResult("create v2")
}
// 其他接口实现方法略
}
生成的swagger文档如下:

在rpc通信过程中,可以通过ICurrentServiceKey的实例设置要请求的应用接口的serviceKey。
private readonly ICurrentServiceKey _currentServiceKey;
public TestProxyAppService(ITestAppService testAppService,
ICurrentServiceKey currentServiceKey)
{
_testAppService = testAppService;
_currentServiceKey = currentServiceKey;
}
public async Task<string> CreateProxy(TestInput testInput)
{
_currentServiceKey.Change("v2"); //在rpc代理请求之前设置`serviceKey`;
return await _testAppService.Create(testInput);
}
开源地址与文档
github: https://github.com/liuhll/lms
gitee: https://gitee.com/liuhll2/lms
开发者文档: http://docs.lms-fk.com/
lms框架应用服务接口和服务条目详解的更多相关文章
- 【山外笔记-工具框架】iperf3网络性能测试工具详解教程
[山外笔记-工具框架]iperf3网络性能测试工具详解教程 本文下载链接 [学习笔记]iperf3网络性能测试工具.pdf 网络性能评估主要是监测网络带宽的使用率,将网络带宽利用最大化是保证网络性 ...
- 2-4、nginx特性及基础概念-nginx web服务配置详解
Nginx Nginx:engine X 调用了libevent:高性能的网络库 epoll():基于事件驱动event的网络库文件 Nginx的特性: 模块化设计.较好扩展性(不支持模块动态装卸载, ...
- Linux:SSH服务配置文件详解
SSH服务配置文件详解 SSH客户端配置文件 /etc/ssh/ssh——config 配置文件概要 Host * #选项“Host”只对能够匹配后面字串的计算机有效.“*”表示所有的计算机. For ...
- 《手把手教你》系列基础篇(八十三)-java+ selenium自动化测试-框架设计基础-TestNG测试报告-下篇(详解教程)
1.简介 其实前边好像简单的提到过测试报告,宏哥觉得这部分比较重要,就着重讲解和介绍一下.报告是任何测试执行中最重要的部分,因为它可以帮助用户了解测试执行的结果.失败点和失败原因.另一方面,日志记录对 ...
- OpenCV学习C++接口 Mat像素遍历详解
OpenCV学习C++接口 Mat像素遍历详解
- Nginx服务优化详解
Nginx服务优化详解 1.隐藏Nginx版本信息 编辑主配置文件nginx.conf,在http标签中添加代码 server_tokens off;来隐藏软件版本号. 2.更改Nginx服务启动的默 ...
- 微信JS接口汇总及使用详解
这篇文章主要介绍了微信JS接口汇总及使用详解,十分的全面.详尽,包含分享到朋友圈,分享给朋友,分享到QQ,拍照或从手机相册中选图,识别音频并返回识别结果,使用微信内置地图查看位置等接口,有需要的小伙伴 ...
- “全栈2019”Java第六十五章:接口与默认方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- STM32接口FSMC/FMC难点详解
STM32接口FSMC/FMC难点详解 转载 http://blog.sina.com.cn/s/blog_808bca130102x94k.html STM32F767的FMC将外部存储器划分为 ...
随机推荐
- hdu2435最大流最小割
2435 There is a war 题意: 给你一个有向图,其中可以有一条边是无敌的,这条边可以是图中的边,也可以是自己任意加上去的图中没有的边,这条无敌的边不可以摧毁,让1和n无法 ...
- Python 爬虫与HTTP协议简介
爬虫的实际例子: 搜索引擎(百度.谷歌.360搜索等). 伯乐在线. 惠惠购物助手. 数据分析与研究(数据冰山知乎专栏). 抢票软件等. 什么是网络爬虫: 通俗理解:爬虫是一个模拟人类请求网站行为的程 ...
- Andrew Ng机器学习算法入门((六):多变量线性回归方程求解
多变量线性回归 之前讨论的都是单变量的情况.例如房价与房屋面积之前的关系,但是实际上,房价除了房屋面积之外,还要房间数,楼层等因素相关.那么此时就变成了一个多变量线性回归的问题.在实际问题中,多变量的 ...
- layui中时间插件laydate的使用
1.加载layui.js 2.html部分 <div class="layui-inline"> <label class="layui-form-la ...
- 【小技巧】启动Tomcat 提示端口被占用 怎么办?一句命令解决
windows环境: 方法1: 1.win+r 打开黑界面 2.输入命令 netstat -ano|findstr 8080 3.输入命令 taskkill /pid xxxx /f Linux环境: ...
- GDI编程基础
窗口和视口 视口是基于设备的采用的是设备坐标(单位:像素),窗口是基于程序的采用的是逻辑坐标(单位:像素/毫米/厘米等). 在默认的映射模式下,视口是与窗口等同的.但是如果改变其映射模式,则其对应的单 ...
- blazor发布之后 刷新404的解决方法
其实所有单页面应用都一样 只需要在nginx里面配置 location / { root html; index index.html index.htm; rewrite ^/.*/$ / last ...
- Flink去重统计-基于自定义布隆过滤器
一.背景说明 在Flink中对流数据进行去重计算是常有操作,如流量域对独立访客之类的统计,去重思路一般有三个: 基于Hashset来实现去重 数据存在内存,容量小,服务重启会丢失. 使用状态编程Val ...
- 【BUAA软工】Beta阶段测试报告
项目 内容 班级:北航2020春软件工程 博客园班级博客 作业:Beta阶段测试报告 测试报告 发现的bug Beta阶段的bug [已解决]CPP项目无法进行调试 [已解决] 注册界面注册后不能够自 ...
- java基础——创建对象与内部分布
类与对象的关系 类是一种抽象的数据类型,它是对某一类事物整体描述和定义,但是不能代表某一个具体的事物 动物.植物.手机.电脑... Person类,Pet类,Car类,这些类都是用来描述和定义某一类具 ...