基于Netty高性能RPC框架Nifty协议、传输层、编解码

ThriftCodecManager与对象读取在编写服务端代码的时候 , 我们创建了ThriftCodecManager这个对象 , 该对象是用来管理编解码器ThriftCodec的 , 在初始化的时候会创建各种类型的编解码器放到缓存中 ,以供服务处理器ThrfitServiceProcessor使用 。 接下来我们就深入分析这个编解码器管理器 。
通常我们使用的就是默认变成ThriftCodec数组构造方法来创建该对象 , 内部持有guava提供的缓存
private final LoadingCache> typeCodecs;public ThriftCodecManager(ThriftCodec... codecs) {this(new CompilerThriftCodecFactory(ThriftCodecManager.class.getClassLoader()), ImmutableSet.copyOf(codecs));}public ThriftCodecManager(ThriftCodecFactory factory, Set> codecs){this(factory, new ThriftCatalog(), codecs);}复制代码主要分三步来添加编解码器到缓存typeCodecs中 ,

  1. 构造typeCodecs, 根据ThriftType来动态构建编解码器添加到缓存中;使用的是guava cache ,这个东西公司内部基础架构部门也用的不少 , 作为本地缓存提供了挺多的策略 , 非常推荐花半小时学习一下;
  2. 添加支持基本类型的编解码器 , 比如StringThriftCodec, IntThriftCodec;
  3. 将我们自己定义的编解码器也加入到缓存中;
接下来按照顺序依次介绍
1.1. 读取集合类型参数typeCodecs = CacheBuilder.newBuilder().build(new CacheLoader>() {public ThriftCodec load(ThriftType type) throws Exception {switch (type.getProtocolType()) {case STRUCT: {return factory.generateThriftTypeCodec(ThriftCodecManager.this, type.getStructMetadata());}case MAP: {ThriftCodec keyCodec = typeCodecs.get(type.getKeyType());ThriftCodec valueCodec = typeCodecs.get(type.getValueType());return new MapThriftCodec<>(type, keyCodec, valueCodec);}case SET: {ThriftCodec elementCodec = typeCodecs.get(type.getValueType());return new SetThriftCodec<>(type, elementCodec);}case LIST: {ThriftCodec elementCodec = typeCodecs.get(type.getValueType());return new ListThriftCodec<>(type, elementCodec);}}}});复制代码【基于Netty高性能RPC框架Nifty协议、传输层、编解码】比如ThriftType=MAP , 分别从缓存获取key和value的编解码器 , 从而来构建map的编解码器MapThriftCodec
在这之前需要知道编解码器其实就是提供了read和write方法,从协议中读取和写出数据 。
public interface ThriftCodec{/*** The Thrift type this codec supports.The Thrift type contains the Java generic Type of the* codec.*/public ThriftType getType();/*** Reads a value from supplied Thrift protocol reader.** @param protocol the protocol to read from* @return the value; not null* @throws Exception if any problems occurred when reading or coercingthe value*/public T read(TProtocol protocol)throws Exception;/*** Writes a value to the supplied Thrift protocol writer.** @param value the value to write; not null* @param protocol the protocol to write to* @throws Exception if any problems occurred when writing or coercingthe value*/public void write(T value, TProtocol protocol)throws Exception;}复制代码基本类型的编解码器在之前的博客中说过 , 这里就看下MapThriftCodec和基本类型的编解码器有什么不同 。
public Map read(TProtocol protocol) throws Exception {return new TProtocolReader(protocol).readMap(keyCodec, valueCodec);}复制代码