传统编码方式转 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). ...
随机推荐
- QuartzNet在winform中使用(目前版本3.6)
界面图"没有什么技术含量~ 不过还是有部分人不太了解的 接下来一一解析下,勿q 使用步骤: 1.初始化帮助类 QuarztHelper x = new QuarztHelper(); 2 ...
- 【学习日志】MongoDB为什么选择B树,而MySQL选择B+树实现索引
先说B树和B+树的区别 B树:非叶子节点也存储数据 B+树:只有叶子节点存储数据,且所有叶子节点通过指针相连接. 为什么MongoDB选择B树而,MySQL选择B+树呢?两种数据结构的区别摆在上面了, ...
- 【rust】rsut基础:模块的使用一、mod 关键字、mod.rs 文件的含义等
本文内容 这篇文章是实战性质的,也就是说原理部分较少,属于经验总结,rust对于模块的例子太少了.rust特性比较多(悲),本文的内容可能只是一部分,实现方式也不一定是这一种. 关于 rust 模块的 ...
- JAVA虚拟机13-字节码指令简介
1.简介 Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需的参数(称为操作数,Operand)构成.JVM指令=1字节 ...
- JAVA虚拟机05-内存溢出示例(jdk1.8)
1.JAVA虚拟机堆内存溢出OutOfMemoryError 1.1设置参数 -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError 最小堆的大小20m 最大堆 ...
- python 取整方法
1.向下取整: int() 2.向上取整:ceil() 使用ceil()方法时需要导入math模块,例如 3.四舍五入:round() 4.分别取 将整数部分和小数部分分别取出,可以使用math模块中 ...
- Netty进阶
1.Netty问题 TCP协议都存在着黏包和半包问题,但是UDP没有 1.粘包现象 发送方分10次发送,接收方一次接受了10次发送的消息 2.半包现象 调整服务器的接受缓冲区大小(调小) 半包会导致服 ...
- boot-repair
sudo add-apt-repository ppa:yannubuntu/boot-repair && sudo apt-get update sudo apt-get insta ...
- JAVA 进阶第一阶段 59-69
10/10号笔记 私有与公共 用private在类中定义的成员变量 只有在这个类的内部才支持访问和编写 public 公共的 用这个定义的在任何地方都可以访问 比如public calss clock ...
- linux下删除文件夹的软链接时注意千万不能在后面加反斜杠,千万不要用强制删除,否则下面2种场景,你会把源文件删除,要闯祸的
今天遇到一个坑,自己在子目录下创建了父目录的软链接,导致可以无限循环进入父目录 [clouder@ana53 dir1]$ ll total 8 -rw-rw-r-- 1 clouder cloude ...