现在上网搜grpc的教程,绝大多数都是底层基于TCP的grpc实现。grpc默认使用TCP方式进行连接,但是如果是本地进程之间进行相互调用的话,采用TCP将会产生很大的不必要的通信开销。而如果基于Unix域套接字,速度可以比TCP套接字快得多。本文采用golang实现了grpc底层使用unix域套接字。
首先在网上给的grpc示例中,服务器端的代码一般是这种形式:
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatal("fialed to resolve unix addr")
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})//设置服务器端的方法供客户端调用
s.Serve(lis)
net.Listen方法返回一个net.Listener对象,对应着服务器端的监听套接字,而net.UnixListener实现了net.Listener接口,s.Serve中的参数改为net.UnixListener即可,服务器端底层即可采用Unix域套接字。
修改完后的代码为:
server_addr, err := net.ResolveUnixAddr("unix", server_file)
if err != nil {
log.Fatal("fialed to resolve unix addr")
}
lis, err := net.ListenUnix("unix", server_addr)
if err != nil {
log.Fatal("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
s.Serve(lis)
其中server_file为Unix域套接字对应的路径,此时lis类型为*net.UnixListener
客户端的实现相对来说比较复杂,不过只要有耐心去分析以下grpc的源码,其实实现原理也不算太难。首先先介绍一下grpc的代码中定义的一些数据类型:
DialOption数据类型:func(*dialOptions). DialOption数据类型为一个函数指针,指向的函数为返回类型为void,参数为dialOptions指针。
dialOptions数据类型&#