Rpc服务AOP
定义
一、说明
Rpc服务在被调用时,会触发一系列的Rpc筛选器AOPIRpcActionFilter的特性(Attribute),进行相关AOP操作。所以可以利用该特性做很多有关Rpc的AOP操作。
通过RpcActionFilter,你可以实现:
- 日志记录:记录方法调用的详细信息
- 权限验证:在方法执行前验证用户权限
- 异常处理:全局捕获和处理RPC调用异常
- 性能监控:统计方法执行时间
- 参数验证:在方法执行前验证参数有效性
RpcActionFilter特性基于AOP(面向切面编程)思想,可以在不修改业务代码的情况下,为RPC方法添加横切关注点功能。
二、支持的特性方法
| 方法名 | 触发时机 | 功能 |
|---|---|---|
| ExecutingAsync | 在执行Rpc之前 | 当invokeResult的InvokeStatus不为InvokeStatus.Ready。则不会执行Rpc。同时,当InvokeStatus为Success。会直接返回结果 |
| ExecutedAsync | 在执行Rpc后 | 如果修改invokeResult的InvokeStatus,或Result。则会影响Rpc最终结果 |
三、使用
3.1 定义RpcActionFilterAttribute特性
要使用RpcActionFilter,首先需要创建一个继承自RpcActionFilterAttribute的特性类,并重写相应的方法。
3.1.1 基础日志记录特性
3.1.2 权限验证特性
通过在ExecutingAsync方法中检查用户权限,可以实现访问控制:
3.1.3 全局异常处理特性
在ExecutedAsync方法中捕获异常,实现统一的异常处理:
使用RpcActionFilterAttribute特性,不仅可以实现日志记录,还可以实现访问权限限制、全局异常捕捉、性能监控等功能。
3.2 在类上使用特性
RpcActionFilterAttribute特性可以应用到RPC服务类上,这样类中的所有方法都会受到该特性的影响:
3.3 在接口上使用特性
特性也可以应用到接口及接口方法上:
3.4 启动服务示例
3.5 测试调用
3.6 规则
RpcActionFilter特性的应用遵循以下规则:
- 应用位置:标签可以添加在
方法、注册接口或注册服务上均会生效。 - 执行顺序:标签生效顺序为
接口方法(如果有)→服务方法→注册接口(如果有)→服务类。 - 去重机制:同一类型的标签仅生效一次。
- 互斥特性:继承的特性,可以通过
MutexAccessTypes属性来标识以哪个类型作为同一特性标识。
3.6.1 执行顺序示例
以下代码展示了特性的执行顺序。执行顺序依次为:MyRpcActionFilter1 → MyRpcActionFilter3 → MyRpcActionFilter2 → MyRpcActionFilter4。
[MyRpcActionFilter2]
interface IMyRpcServer : ISingletonRpcServer
{
[MyRpcActionFilter1]
int Add(int a, int b);
}
[MyRpcActionFilter4]
class MyRpcServer :SingletonRpcServer, IMyRpcServer
{
[MyRpcActionFilter3]
public int Add(int a, int b)
{
return a + b;
}
}
3.6.2 去重机制示例
以下代码中,虽然MyRpcActionFilter特性被应用了4次,但只会执行一次:
[MyRpcActionFilter]
interface IMyRpcServer : ISingletonRpcServer
{
[MyRpcActionFilter]
int Add(int a, int b);
}
[MyRpcActionFilter]
class MyRpcServer :SingletonRpcServer, IMyRpcServer
{
[MyRpcActionFilter]
public int Add(int a, int b)
{
return a + b;
}
}
3.6.3 互斥特性示例
通过设置MutexAccessTypes属性,可以让不同的特性类互斥。在以下代码中,MyAttribute和My2Attribute都继承自MyBaseAttribute,由于基类指定了互斥类型,因此在同一个方法上只有一个会生效(按优先级)。
定义互斥特性基类:
定义互斥特性子类:
应用互斥特性:
互斥特性在实际应用中,应该谨慎使用。确保互斥逻辑符合业务需求,避免出现预期之外的行为。
四、常见应用场景
4.1 日志记录
RpcActionFilter最常见的用途是记录RPC调用日志,包括方法名、参数、执行时间等信息。
4.2 权限验证
在方法执行前验证调用者是否有权限访问该方法,可以实现细粒度的访问控制。
4.3 异常处理
统一处理RPC调用过程中的异常,将技术异常转换为用户友好的错误信息。
4.4 性能监控
记录方法的执行时间,用于性能分析和优化。
4.5 参数验证
在方法执行前验证参数的有效性,提前拦截无效请求。
4.6 缓存处理
对于查询类方法,可以在ExecutingAsync中检查缓存,如果命中缓存直接返回,避免执行实际方法。
五、最佳实践
5.1 特性命名规范
- 特性类名应该以
Attribute结尾 - 使用描述性的名称,清晰表达特性的用途
- 例如:
LoggingFilterAttribute、AuthorizationFilterAttribute
5.2 性能考虑
- 避免在ExecutingAsync和ExecutedAsync中执行耗时操作
- 如果需要执行耗时操作,考虑使用异步方式
- 注意特性的执行顺序,避免不必要的重复操作
5.3 异常处理
- 在特性方法中妥善处理异常,避免影响正常的RPC调用
- 记录异常信息,便于问题排查
5.4 状态管理
- 通过
InvokeResult对象传递状态和结果 - 合理使用
InvokeStatus枚举值表示不同的执行状态
六、总结
RpcActionFilter提供了一种优雅的方式来实现RPC服务的横切关注点,通过特性的方式可以在不修改业务代码的情况下,为RPC方法添加各种功能。合理使用RpcActionFilter可以提高代码的可维护性和可扩展性。