grpc c++版本,自定义naming resolver

=编译grpc=,保证系统protobuf和grpc相应版本一致,gprc每个版本都会提供third_party/protobuf,可以直接进去sudo make install把当前系统的protoc给改了。make不过主要就是proto不一致的事。

=理解Makefile=,目的是libgrpc.a中引入自研的naming service sdk,如下:

// 你可以直接在Makefile中写sdk的compile和link的过程,也可以提前编译好
// 这里罗列cc文件的唯一目的就是为了生成下面的WEBFOOT_MERGE_OBJS,在连接libgrpc.a的时候使用
LIBWEBFOOT_SRC = \
    /home/lihao/grpc/third_party/naming-webfoot/webfootremote.cc \
    /home/lihao/grpc/third_party/naming-webfoot/webfoot.cc \
    /home/lihao/grpc/third_party/naming-webfoot/service.grpc.pb.cc \
    /home/lihao/grpc/third_party/naming-webfoot/webfoot_c.cc \
    /home/lihao/grpc/third_party/naming-webfoot/service.pb.cc \
    /home/lihao/grpc/third_party/naming-webfoot/webfootremote_c.cc \

WEBFOOT_DEP = /home/lihao/grpc/third_party/naming-webfoot/output/lib/libwebfoot.a
WEBFOOT_MERGE_LIBS = /home/lihao/grpc/third_party/naming-webfoot/output/lib/libwebfoot.a
WEBFOOT_MERGE_OBJS = $(addsuffix .o, $(basename $(LIBWEBFOOT_SRC)))

// grpc使用webfoot,需要找webfoot的header文件,这个就是在链接libgrpc.a的时侯去这里找
CPPFLAGS += -Ithird_party/naming-webfoot/

编译naming service sdk问题主要就是,proto文件需要使用grpc依赖的protobuf重新生成代码。

=naming service sdk=链接进去之后,下一件事,是仿照dns resolver实现自己的resolver plugin。虽然是抄还是要,搞清楚resolver.h中定义的Resolver接口每个方法是干什么用的。目录如下:src/core/ext/filters/client_channel/resolver。

=resolver=开发主要是理解dns resolver中的各种机制,不要完全照抄。这里还遇到个问题,是当下游服务的ip列表变化的时侯,native dns resolver不能检测到这个更新,这样在扩容机器的时侯就需要重启服务,关于这个问题的讨论:

https://github.com/grpc/grpc-java/issues/2514
https://github.com/grpc/grpc/issues/12295

当前机制是这样的,启动服务后,会加载dns对应的所有下游endpoint,如果下游某个endpoint挂了,会不断检测,这个检测有个backoff,仿照tcp探活机制,不是有规律的是不均匀的向后推迟探测时机。直到下游恢复,grpc会恢复下游的流量。

完成之后,make出来libgrpc.a 就可以用了。下面贴下关键代码:

namespace grpc_core {

const char kDefaultPort[] = "https";

namespace {

class SfnsResolver : public Resolver {
 public:
  explicit SfnsResolver(const ResolverArgs& args);

  void NextLocked(grpc_channel_args** result,
                  grpc_closure* on_complete) override;

  void RequestReresolutionLocked() override;

  void ResetBackoffLocked() override;

  void ShutdownLocked() override;


 private:
  virtual ~SfnsResolver();

  void MaybeStartResolvingLocked();
  void StartResolvingLocked();
  void MaybeFinishNextLocked();

  static void OnNextResolutionLocked(void* arg, grpc_error* error);
  static void OnResolvedLocked(void* arg, grpc_error* error);
};

class SfnsResolverFactory : public ResolverFactory {
 public:
  OrphanablePtr<Resolver> CreateResolver(
      const ResolverArgs& args) const override {
    return OrphanablePtr<Resolver>(New<SfnsResolver>(args));
  }

  const char* scheme() const override { return "sfns"; }
};

}  // namespace

}  // namespace grpc_core



void grpc_resolver_sfns_init() {
  grpc_core::ResolverRegistry::Builder::InitRegistry();
  grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
    grpc_core::UniquePtr<grpc_core::ResolverFactory>(
        grpc_core::New<grpc_core::SfnsResolverFactory>()));
}

void grpc_resolver_sfns_shutdown() {}

同时还要在src/core/plugin_registry/grpc_plugin_registry.cc 和 src/core/plugin_registry/grpc_unsecure_plugin_registry.cc中注册你的plugin。

grpc c++版本,自定义naming resolver
Share this