RPCX分布式服务框架主要致力于提供高性能和透明化的RPC远程服务调用。
RPCX框架可能考虑到扩展性(猜测而已),增加了一个插件功能,引入了插件接口,如下:
type PluginContainer interface {
Add(plugin Plugin)
Remove(plugin Plugin)
All() []Plugin
DoRegister(name string, rcvr interface{}, metadata string) error
DoRegisterFunction(name string, fn interface{}, metadata string) error
DoUnregister(name string) error
DoPostConnAccept(net.Conn) (net.Conn, bool)
DoPostConnClose(net.Conn) bool
DoPreReadRequest(ctx context.Context) error
DoPostReadRequest(ctx context.Context, r *protocol.Message, e error) error
DoPreWriteResponse(context.Context, *protocol.Message, *protocol.Message) error
DoPostWriteResponse(context.Context, *protocol.Message, *protocol.Message, error) error
DoPreWriteRequest(ctx context.Context) error
DoPostWriteRequest(ctx context.Context, r *protocol.Message, e error) error
}
在一些关键事件中会进行PreXXX调用,处理完流程后会进行PostXXX调用,如代码:
func (s *Server) readRequest(ctx context.Context, r io.Reader) (req *protocol.Message, err error) {
err = s.Plugins.DoPreReadRequest(ctx)
if err != nil {
return nil, err
}
// pool req?
req = protocol.GetPooledMsg()
err = req.Decode(r)
perr := s.Plugins.DoPostReadRequest(ctx, req, err)
if err == nil {
err = perr
}
return req, err
}
再例如注册中心也是利用插件机制实现的,如代码:
向服务提供方实例添加zookeeper注册中心
plugin := &serverplugin.ZooKeeperRegisterPlugin{
ServiceAddress: "tcp@192.168.10.25:"+*port,
ZooKeeperServers: []string{"192.168.10.25:2181"},
BasePath: "/rpcx_test",
Metrics: metrics.NewRegistry(),
UpdateInterval: time.Minute,
}
if err := plugin.Start();err != nil {
server.Close()
os.Exit(1)
}else{
server.Plugins.Add(plugin)
}
server.Plugins.Add(&plugin2.PluginAll{})
func (s *Server) RegisterName(name string, rcvr interface{}, metadata string) error {
if s.Plugins == nil {
s.Plugins = &pluginContainer{}
}
s.Plugins.DoRegister(name, rcvr, metadata) //调用注册中心实际处理函数
_, err := s.register(rcvr, name, true)
return err
}
系列文章