传统编码方式转 gRPC 注意事项
# 赋值编码:
1.pbBuilder 设置值时不能为 null
2.pb 定义的类是不可变类,赋值时需要使用 Builder 模式,且每次 builder 都会 new 一个新对象,所以赋值时需要特别留意
3.pbData.setList(),原有 list 属性不会被覆盖,需要手动清除 pbData.clean()
4.entity A 与 pb 类互相拷贝属性时,如果 A 中包含类 B 是不会拷贝的,需要手动处理
5.Controller 接口参数使用 pbBuilder 类模式才能接收到值
# 业务影响:
1.pb 属性都会有默认值,所以业务字段上0,空字符串这些判断处理时需要特别处理
# 框架整合
1.整合 skywalking 时,因为异步调用原因,客户端不能透传 traceId 到服务端,导致服务端日志文件不能输出 traceId,目前采用 grpc 客户端、服务端拦截 + MDC 方式处理
@Component
public class GrpcClientLogInterceptor implements ClientInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(GrpcClientLogInterceptor.class); @Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
@Override
public void start(Listener<RespT> responseListener, Metadata headers) {
String traceId = MDC.get(LogConstants.MDC_GRPC_TRACE_KEY); if (StringUtils.isBlank(traceId)) {
traceId = UuidUtils.randomUUIDStr32();
LOGGER.debug("调用方法前未获取 traceId,生成新的 traceId:[{}],methodName:[{}]", traceId, method.getFullMethodName());
}
headers.put(LogConstants.REQUEST_KEY, traceId); super.start(responseListener, headers);
}
};
}
} @Component
public class GrpcServerLogInterceptor implements ServerInterceptor { private static final Logger LOGGER = LoggerFactory.getLogger(GrpcServerLogInterceptor.class); @Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata,
ServerCallHandler<ReqT, RespT> serverCallHandler) {
final long startTime = System.currentTimeMillis();
String fullMethodName = serverCall.getMethodDescriptor().getFullMethodName(); String traceId = metadata.get(LogConstants.REQUEST_KEY);
if (StringUtils.isBlank(traceId)) { traceId = UuidUtils.randomUUIDStr32();
LOGGER.debug("调用方法前未获取 traceId,生成新的 traceId: [{}],methodName:[{}]", traceId, fullMethodName);
} MDC.put(LogConstants.MDC_GRPC_TRACE_KEY, traceId); LOGGER.debug("server recive traceId: {}", traceId);
LOGGER.debug("Before request [method={}]", fullMethodName);
LOGGER.debug("GRPC Metadata: {}", metadata); ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT> serverCall1 =
new ForwardingServerCall.SimpleForwardingServerCall(serverCall) {
@Override
public void sendMessage(Object message) {
super.sendMessage(message);
}
}; ServerCall.Listener<ReqT> listener = serverCallHandler.startCall(serverCall1, metadata); final String finalTraceId = traceId;
return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(listener) {
@Override
public void onMessage(ReqT message) {
LOGGER.debug("GRPC Request: {}", message);
super.onMessage(message);
} @Override
public void onComplete() {
LOGGER.debug("After request [method={}],grpc request elapsed time:{}ms.", fullMethodName, (System.currentTimeMillis() - startTime));
super.onComplete(); MDC.remove(LogConstants.MDC_GRPC_TRACE_KEY);
LOGGER.debug("After request [method={}], 删除 MDC 中 traceId [{}].", fullMethodName, finalTraceId);
}
};
}
} public class LogConstants { // grpc head key
public static final String GRPC_REQUEST_ID = "request-id-bin";
public static final String UTF_8 = "UTF-8";
public static final String MDC_GRPC_TRACE_KEY = "GTID"; /**
* 公共 key,透传 traceid 时的 key
*/
public static final Metadata.Key<String> REQUEST_KEY = Metadata.Key.of(GRPC_REQUEST_ID,
new Metadata.BinaryMarshaller<String>() {
@Override
public byte[] toBytes(String value) {
try {
return value.getBytes(UTF_8);
} catch (UnsupportedEncodingException e) {
return null;
}
} @Override
public String parseBytes(byte[] serialized) {
try {
return new String(serialized, UTF_8);
} catch (UnsupportedEncodingException e) {
return null;
}
}
});
}
2.Quartz 框架整合 skywalking,不能输出 traceId,处理方案同上面
3.Qrartz 框架的 Job 类因为是采用 AdaptableJobFactory.createJobInstance 方式生成示例,导致不能直接注入 grpc 服务类。
解决方案:业务处理放入到 Spring bean 业务类中,再依赖注入到 Job 实例
传统编码方式转 gRPC 注意事项的更多相关文章
- Oracle EBS在编码方式为AL32UTF8时的注意事项
现如今的EBS系统中,为了推进国际化的进程,以及系统向全球化的扩展,在Oracle数据库的编码方式上渐渐从支持中国本土简体中文的ZHS16GBK转向了更趋于国际化的AL32UTF8编码方式.但随之而来 ...
- Redis与KV存储(RocksDB)融合之编码方式
Redis与KV存储(RocksDB)融合之编码方式 简介 Redis 是目前 NoSQL 领域的当红炸子鸡,它象一把瑞士军刀,小巧.锋利.实用,特别适合解决一些使用传统关系数据库难以解决的问题.Re ...
- 【python】python编码方式,chardet编码识别库
环境: python3.6 需求: 针对于打开一个文件,可以读取到文本的编码方式,根据默认的文件编码方式来获取文件,就不会出现乱码. 针对这种需求,python中有这个方式可以很好的解决: 解决策略: ...
- MIME协议(五) -- MIME邮件的编码方式
5 MIME邮件的编码方式 由于每个ASCII码字符只占用一个字节(8个bit位),且最高bit位总为0,即ASCII码字符中的有真正意义的信息只是后面的7个低bit位,而传统的SMTP协议又是基于 ...
- VUE 开发报表,非编码方式
官网:http://doc.sougn.com 下载地址:https://pan.baidu.com/share/init?surl=P0O9sjfzC8nuQxirDfjW1A 密码:4oev 先 ...
- Java不同编码方式,中英文字符所占字节数
测试代码 public class Test { public static void main(String[] args){ String[] charsetNames={ "UTF-8 ...
- form表单编码方式设置为multipart/form-data,后台参数出现乱码情况
一般在上传图片过程中,form中的编码方式一般采用multipart/form-data方式编码,但是后台这取参数时,可能会出现乱码情况:这里后台要采用转换编码方式: 页面: 后台:获取表单元素时,
- servlet获取表单数据的方式和编码方式
.在servlet中获取表单的数据的几种方式 1>request.getParameter(“name”)://获取指定名称的值,返回值类型是一个字符串 2>request.getPa ...
- python 改变字符串的编码方式
字符串str的编码方式为utf-8,转化为gbk,分为两步 1. str=str.decode('utf-8') 2. str=str.encode('gbk')
- [No000040]取得一个文本文件的编码方式
using System; using System.IO; using System.Text; /// <summary> /// 用于取得一个文本文件的编码方式(Encoding). ...
随机推荐
- 算法学习笔记(17): 快速傅里叶变换(FFT)
快速傅里叶变换(FFT) 有趣啊,都已经到NOI的难度了,救命 首先,我们先讲述一下前置知识.已经明白的读者请移步后文 虚数 定义:\(z = a + bi\),其中 \(a, b \in R\ \ ...
- 【LeetCode字符串#05】基于个人理解的KMP算法图解,以及应用到strStr()函数实现
KMP算法(用于实现 strStr()) strStr()函数是用来在一个字符串中搜索是否存在另一个字符串的函数,其匹配字符串方式为KMP算法 KMP算法基础理论 假设有如下两个字符串 文本串 aab ...
- 【Oculus Interaction SDK】(七)使用射线进行交互(物体 & UI)
前言 这篇文章是[Oculus Interaction SDK]系列的一部分,如果发现有对不上的对方,可以回去翻看我之前发布的文章,或在评论区留言.如果文章的内容已经不适用于新版本了,也可以直接联系我 ...
- Windows Server 2016 安装AD和Exchange
一.AD虚拟机操作 1.安装net framework 4.8 下载链接:https://dotnet.microsoft.com/download/dotnet-framework/net48 安装 ...
- el-input 限制只能输入正整数
1.前端页面 <el-row :gutter="20"> <el-col :span="20"> <el-form-item la ...
- Vue3
VUE.3 1.前端工程化: 小白视角 会写HTML. css.JavaScript就会前端开发 需要美化页面的样式,就拽一个bootstrap来 需要操作DOM或者发起Ajax请求,就再拽一个Jqu ...
- Redhat7.6搭建LAMP环境
关闭防火墙和 selinux# systemctl stop firewalld systemctl disable firewalld 禁用 Selinux vim /etc/selinux/con ...
- 修改ctags让fzf.vim插件显示C,C++方法声明的标签
背景 在 vim 中使用 fzf.vim 插件可以进行方便的搜索文件, 源码TAG, GIT 记录等, 最近抽空看了下 BTags 命令在 c, c++ 文件中, 无法显示头文件中的函数声明 标签问题 ...
- JZOJ 1083. 【GDOI2006】拯救亚特兰蒂斯
\(\text{Solution}\) 自己的网络流技术太拉了 连这样的题都做不出来 对于一个怪物,剑术和法术两样东西有一样就可以了 不难想到二分图中最小点覆盖,一条边只有两个端点之一被选就被覆盖了 ...
- C# 数字转大写汉字
1.数字转换成汉字大写public string NumToChinese(string x) { //数字转换为中文后的数组 string[] P_array_num = new string[] ...