go grpc 设置返回头信息_跟我学 gRPC—6.Unary and Stream interceptor

Go语言中文网,致力于每日分享编码、开源等知识,欢迎关注我,会有意想不到的收获!

项目地址:https://github.com/EDDYCJY/go-grpc-example

前言

我想在每个 RPC 方法的前或后做某些事情,怎么做?

本章节将要介绍的拦截器(interceptor),就能帮你在合适的地方实现这些功能

有几种方法

在 gRPC 中,大类可分为两种 RPC 方法,与拦截器的对应关系是:

  • 普通方法:一元拦截器(grpc.UnaryInterceptor)
  • 流方法:流拦截器(grpc.StreamInterceptor)

看一看

grpc.UnaryInterceptor

146cb9f14a967cb0df8e17e6b2ac2b30.png

通过查看源码可得知,要完成一个拦截器需要实现 UnaryServerInterceptor 方法。形参如下:

  • ctx context.Context:请求上下文
  • req interface{}:RPC 方法的请求参数
  • info *UnaryServerInfo:RPC 方法的所有信息
  • handler UnaryHandler:RPC 方法本身

grpc.StreamInterceptor

func StreamInterceptor(i StreamServerInterceptor) ServerOptiontype StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error

StreamServerInterceptor 与 UnaryServerInterceptor 形参的意义是一样,不再赘述

如何实现多个拦截器

另外,可以发现 gRPC 本身居然只能设置一个拦截器,难道所有的逻辑都只能写在一起?

关于这一点,你可以放心。采用开源项目 go-grpc-middleware 就可以解决这个问题,本章也会使用它

72feba6724759f5ea0cd645363911790.png

gRPC

从本节开始编写 gRPC interceptor 的代码,我们会将实现以下拦截器:

  • logging:RPC 方法的入参出参的日志输出
  • recover:RPC 方法的异常保护和日志输出

实现 interceptor

logging

53fc46435def45f0dec551934a3b2cfc.png

recover

e12701f068ba1e51d1c84cda2c7cfc6f.png

Server

a62488f70e7e3f1f6649fbe46db295bf.png

验证

logging

启动 simple_server/server.go,执行 simple_client/client.go 发起请求,得到结果:

$ go run server.go2018/10/02 13:46:35 gRPC method: /proto.SearchService/Search, request:"gRPC" 2018/10/02 13:46:35 gRPC method: /proto.SearchService/Search, response:"gRPC Server"

recover

在 RPC 方法中人为地制造运行时错误,再重复启动 server/client.go,得到结果:

client

$ go run client.go2018/10/02 13:19:03 client.Search err: rpc error: code = Internal desc = Panic err: assignment to entry in nil mapexit status 1

server

72696584e0d791d11050ba8ecf583361.png

检查服务是否仍然运行,即可知道 Recovery 是否成功生效

总结

通过本章节,你可以学会最常见的拦截器使用方法。接下来其它“新”需求只要举一反三即可

参考

本系列示例代码

  • go-grpc-example

本文作者:煎鱼,原创授权发布

pyfluent.launcher ERROR: Exception caught - RuntimeError: Deadline Exceeded Traceback (most recent call last): File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\ansys\fluent\core\launcher\standalone_launcher.py", line 281, in __call__ session = self.new_session._create_from_server_info_file( server_info_file_name=self._server_info_file_name, ...<4 lines>... inside_container=False, ) File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\ansys\fluent\core\session.py", line 332, in _create_from_server_info_file fluent_connection = FluentConnection( ip=ip, ...<3 lines>... **connection_kwargs, ) File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\ansys\fluent\core\fluent_connection.py", line 446, in __init__ self._health_check.check_health() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^ File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\ansys\fluent\core\services\health_check.py", line 82, in check_health response = self._stub.Check( request, metadata=self._metadata, timeout=pyfluent.CHECK_HEALTH_TIMEOUT ) File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\grpc\_interceptor.py", line 277, in __call__ response, ignored_call = self._with_call( ~~~~~~~~~~~~~~~^ request, ^^^^^^^^ ...<4 lines>... compression=compression, ^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\grpc\_interceptor.py", line 329, in _with_call call = self._interceptor.intercept_unary_unary( continuation, client_call_details, request ) File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\ansys\fluent\core\services\interceptors.py", line 172, in intercept_unary_unary return self._intercept_call(continuation, client_call_details, request) ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\ansys\fluent\core\services\interceptors.py", line 162, in _intercept_call raise new_ex from None RuntimeError: Deadline Exceeded The above exception was the direct cause of the following exception: Traceback (most recent call last): File "E:\download\pyfluent-main\pyfluent-main\examples\piont.py", line 5, in <module> session = pyfluent.launch_fluent( product_version = 251, ...<6 lines>... show_gui=True ) File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\ansys\fluent\core\utils\deprecate.py", line 73, in wrapper return decorated(*args, **kwargs) File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\deprecated\classic.py", line 199, in wrapper_function return wrapped_(*args_, **kwargs_) File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\ansys\fluent\core\utils\deprecate.py", line 118, in wrapper return func(*args, **kwargs) File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\ansys\fluent\core\utils\deprecate.py", line 118, in wrapper return func(*args, **kwargs) File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\ansys\fluent\core\launcher\launcher.py", line 352, in launch_fluent return launcher() File "C:\Users\asus\.conda\envs\fluent\Lib\site-packages\ansys\fluent\core\launcher\standalone_launcher.py", line 323, in __call__ raise LaunchFluentError(self._launch_cmd) from ex ansys.fluent.core.launcher.error_handler.LaunchFluentError: Fluent Launch string: start "" "D:\ANSYS Inc\v251\fluent\ntbin\win64\fluent.exe" 3ddp -py -t12 -meshing -sifile=C:\Users\asus\AppData\Local\Temp\serverinfo-b0g6fdge.txt -nm
最新发布
08-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值