近期学习gin,goropcache,gorm项目的源码,发现所谓框架就是本质上的原生封装。并对模仿乐此不疲。
拿gin举例,几乎没有实现难点,go的net原生已经堪称完美,路由上的分组处理也只是一种解析思维,整天上还是handler func的中间式处理。
gocache的实现无非是针对缓存的三个临界效应做捕获处理,gorm这种orm框架,这次原生的尝试发现主要的难点就是对于反射的掌握,其实本质上不就是将struct和func平铺成sql语句或者反过来。
分别对三个都进行了实现,如果说学到了什么,我认为没有接触太底层的东西,主要还是高手的代码风格和模块分化,go这种模块化的思维,简直甩mvc这种几条街。再就是学习一些好的习惯,比如gin的实现代码5k+,测试代码有9k+。
源码学习是作用远大于在一个借助一个框架如何实现一个blog的backend,近期将继续研究golang语言
po一段gorpc的封装代码,我认为serverless远没有那么高深莫测,实际上就是玩协议,如果有很高的技术难点,就不可能有那么多人在谈,如果津津乐道的人不知道网络协议,你可以认为他是一个骗子。
接口规范
package rpcdemo import "net/rpc" const HelloServiceName = "path/..." type HelloServiceClient struct { *rpc.Client } var _ HelloServiceInterface = (*HelloServiceClient)(nil) type HelloServiceInterface interface { Hello(request string, relay *string) error } func DialHelloService(network, address string) (*HelloServiceClient, error) { c, err := rpc.Dial(network, address) if err != nil { return nil, err } return &HelloServiceClient{Client:c}, nil } func RegisterHelloService(svc HelloServiceInterface) error { return rpc.RegisterName(HelloServiceName, svc) } func (p *HelloServiceClient) Hello(request string, reply *string) error { return p.Client.Call(HelloServiceName+".Hello", request, reply) }
客户端
package rpcdemo import ( "log" ) func main() { client, err := DialHelloService("tcp", "localhost:9999") if err != nil { log.Fatal("dialing...", err) } var reply string err = client.Hello("hello", &reply) if err != nil { log.Fatal(err) } }
服务端
package rpcdemo import ( "log" "net" "net/rpc" ) type HelloService struct { } func (p *HelloService) Hello(request string, reply *string) error { *reply = "hello" + request return nil } func main() { RegisterHelloService(new(HelloService)) listener, err := net.Listen("tcp", "localhost:9999") if err != nil { log.Fatal("listenTCP error", err) } for { conn, err := listener.Accept() if err != nil { } go rpc.ServeConn(conn) } }
end