在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本章节我将专注于开发第一个微服务系统,我们将学会如何用go chassis开发微服务并完成微服务之间的调用 系列1https://xie.infoq.cn/article/f658d19b6f22f9d9bac1dfe75 开发你的第一个微服务启动注册中心docker run -d -p 30100:30100 servicecomb/service-center 强烈推荐直接使用all in one的docker compose模板启动,因为可以使用可视化的UI界面。 https://github.com/go-chassis/go-chassis/blob/master/examples/docker-compose.yaml
初始化Go工程go mod init github.com/go-chassis/go-chassis-examples/hello go get github.com/go-chassis/go-chassis/v2 工程目录规划可以创建一个server(名称任意)文件夹,这个就是一个微服务的目录 mkdir server 目录结构 server +-- main.go +-- conf +-- chassis.yaml +-- microservice.yaml 最小化配置在chassis.yaml中涵盖了几乎所有的配置,不过想要启动只需要2个简单的配置 servicecomb: registry: address: http://127.0.0.1:30100 protocols: rest: listenAddress: 127.0.0.1:9000 也就是服务监听地址和注册中心地址 在microservice.yaml里定义微服务信息,只需要一个简单的微服务名即可,它还有大量的其他高级特性,我们将后续在高级特性中介绍 servicecomb: service: name: HelloServer 编写业务逻辑是时候编写自己的API了 //通常持有一批API,并定义API Patterns type HelloResource struct { } //业务API func (r *HelloResource) SayHi(b *rf.Context) { b.Write([]byte("hello, go chassis")) return } //定义所有的API Patterns,用于API路由 func (r *HelloResource) URLPatterns() []rf.Route { return []rf.Route{ {Method: http.MethodGet, Path: "/hello", ResourceFunc: r.SayHi}, } } 之后仅需要注册即可 chassis.RegisterSchema("rest", &HelloResource{}) 启动服务启动很简单,只需要编写如下内容 if err := chassis.Init(); err != nil { openlog.Fatal("Init failed." + err.Error()) return } chassis.Run() 编译执行 go build main.go ./main 验证:访问UIhttp://127.0.0.1:30103 额外可以看到自动生成的open API文档 直接访问服务 curl http://127.0.0.1:9000/hello 调用服务接着我们需要调用这个服务 创建一个新的微服务 mkdir client 定义微服务在chassis.yaml中定义另一个监听地址 servicecomb: registry: address: http://127.0.0.1:30100 protocols: rest: listenAddress: 127.0.0.1:8000 在microservice.yaml中定义微服务名 servicecomb: service: name: HelloClient #编写客户端 为了简单这里只需要简单的转发即可,这里给出完整逻辑 type SimpleResource struct { } //在这个方法中,调用上面编写的服务 func (r *SimpleResource) SayHi(b *rf.Context) { req, _ := rest.NewRequest(http.MethodGet, "http://HelloServer/hello", nil)//这里要填写需要调用哪个服务,填写服务名即可,然后就是他的api路径 restInvoker := core.NewRestInvoker()//并发安全,可全局使用 resp, err := restInvoker.ContextDo(context.TODO(), req)//执行调用,这时go chassis介入,执行一些列用户不可见的计算和操作 if err != nil { log.Println(err) return } b.Write(httputil.ReadBody(resp))//读出服务端body体并直接透传返回 return } func (r *SimpleResource) URLPatterns() []rf.Route { return []rf.Route{ {Method: http.MethodGet, Path: "/hi", ResourceFunc: r.SayHi}, } } func main() { chassis.RegisterSchema("rest", &SimpleResource{}) if err := chassis.Init(); err != nil { openlog.Fatal("Init failed." + err.Error()) return } chassis.Run() } 验证: go build main.go ./main ## 打开另一个终端,执行 curl http://127.0.0.1:8000/hi 将返回HelloServer的返回结果 此时2个微服务实例应该同时在线 完整例子https://github.com/go-chassis/go-chassis-examples/tree/master/hello 小知识为了提高系统的可用性,我们通常可以通过简单的扩容实例来达成。从概率来说这切实有效。假设一个实例的可用度为0.995. 那么2个实例并联后,他们的可用性为 1-(1-0.995)的平方=0.999975 在访问量大的情况下,我们也期望通过扩容来获得线性的吞吐增长。然而吞吐能力并非随着实例的数量呈线性增长。 通常在给定一个实例的规格后,需要进行benchmark测试找到该规格下,到底多大的实例数量能达到最佳性价比。后续就要通过优化代码来去提升吞吐了。这也是降成本的一种手法。 总结本次,我们学会了开发简单的微服务,并且完成了2者的一次调用。 在实际使用中,可以启动数个服务端实例,提升服务可用性。 go chassis通过客户端负载均衡与注册中新帮助屏蔽了网络拓扑的复杂性,只需要理解服务名即可。 |
请发表评论