Go实践微服务 -- 服务发现

服务的注册发现对于微服务来说是一个非常重要的环节,在单一架构应用中,service 之间的互相调用,通过一个固定的 host 和 port 来发起 REST 或者 RPC 来调用,但是在微服务架构中,各个服务往往是动态变化的,所以需要一个服务发现机制来发送客户端的请求到动态的 service 实例中去。 在利用 go micro 来实现服务发现便利很多,micro 中默认支持使用 Consul 来做服务发现,当然它使用插件机制(go-plugins)还支持 Etcd, Gossip, NATS 等其他的第三方服务注册发现工具。在每个服务启动的时候,都将自己注册到 registry 上,退出时也自动解注册,具体实现我们可以来看一下go-micro/service.go的相关代码片段: ...... func (s *service) run(exit chan bool) { if s.opts.RegisterInterval <= time.Duration(0) { return } //定时注册自己 t := time.NewTicker(s.opts.RegisterInterval) for { select { case <-t.C: err := s.opts.Server.Register() if err != nil { log.Log("service run Server.Register error: ", err) } case <-exit: t.Stop() return } } } .

阅读全文

在之前介绍了《Go 实践微服务 – gRPC 配置和使用》,通过 gRPC 直接编写微服务有点麻烦,比如都需要手动指定服务地址和端口,不便于管理,也需要自己来实现服务注册和发现的逻辑,同时对于网关以及监控等都是微服务架构和实施中不可避免的。所以引入 go-micro,go-micro 是一个插件式的 RPC 框架,它是Micro生态的一部分,Micro 是一个简化分布式开发的微服务生态系统,它为开发分布式应用程序提供了基本的构建模块。 Go Micro 抽象出分布式系统的细节。以下是主要功能。 服务发现 - 通过服务发现自动注册和名称解析 负载平衡 - 基于发现构建的服务的智能客户端负载平衡 同步通信 - 基于 RPC 的通信,支持双向流 异步通信 - 为事件驱动架构内置的 Pub/Sub 接口 消息编码 - 基于带有 protobuf 和 json 的内容类型的动态编码 服务接口 - 所有功能都打包在一个简单的高级界面中,用于开发微服务 通过写一个船运的示例看下 go-micro 如何来写一个微服务。 安装 protoc-gen-micro go get github.com/micro/protoc-gen-micro 编写 proto 文件来定义服务 consignment-service/proto/consignment/consignment.proto syntax = "proto3"; package go.micro.srv.consignment; // 定义货轮服务 service ShippingService { // 托运一批货物 rpc CreateConsignment (Consignment) returns (Response) { } // 查看货物信息 rpc GetConsignments (GetRequest) returns (Response) { } } // 货物信息 message Consignment { string id = 1; // ID string description = 2; // 描述 int32 weight = 3; // 重量 repeated Container containers = 4; // 集装箱,多个 string vessel_id = 5; // 承运货轮ID } // 集装箱 message Container { string id = 1; // 编号 string customer_id = 2; // 客户ID string origin = 3; // 出发地 string user_id = 4; // 集装箱所属用户ID } // 托运结果 message Response { bool created = 1; // 托运结果 Consignment consignment = 2; // 新托运的货物 repeated Consignment consignments = 3; // 所有托运的货物 } message GetRequest { } 生成 gRPC 代码 consignment-service/Makefile

阅读全文

gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。 它有很多特点,如双向流、流控、头部压缩、单 TCP 连接上的多复用请求,节省带宽、降低 TCP 链接次数、节省 CPU 使用和延长电池寿命等。强大的 IDL,默认采用Protocol Buffers数据序列化协议,支持多种开发语言以及移动端。gRPC 既能够在客户端应用,也能够在服务器端应用,从而以透明的方式实现客户端和服务器端的通信和简化通信系统的构建,很容易去构建分布式应用和微服务架构模式。 各大主流的 RPC 框架的性能比较可以参考这一篇《流行的 rpc 框架 benchmark 2018 新春版》 我很久前写过一篇《Thrift 应用总结》 安装 protobuf 编译器 官方推荐使用 protobuf 3,我用的是 Mac,所以可以直接用 brew 安装 3.X 版本 brew info protobuf brew install protobuf 安装完可以看下版本号 protoc --version libprotoc 3.5.1 当然也可以通过编译安装 #去下载Protocol Buffers v3.5.1的release包 brew info automake brew info libtool # 没有这两个就安装 ./autogen.sh # 检查没问题了 ./configure make -j8 make check make install 安装 Golang for protobuf 插件 go get -u -v github.

阅读全文

Go 实现依赖注入

为什么需要依赖注入 作为一名软件开发人员,如果我们希望使代码保持清洁和可维护性,我们将代码分割成不同的层次。 通常边界至少放置在基础设施和业务逻辑之间。当我们专门处理复杂的业务逻辑时,基础架构依赖于我们的业务逻辑是可取的,这样在更改基础架构时不会破坏我们的软件。 开发一个新的软件项目时的第一个决定是否选择一个结构来实现分层。 大多数情况下,我选择简洁的架构,但您有另一个很好的选择,例如 Domain Driven Design(领域驱动设计)。 独立于您选择的架构,我们必须粘贴来自不同模块以提供新功能,而这正是依赖注入所发挥的作用。 如何实现依赖注入 理解依赖注入,没有比示例更好的了。 想象一下,我们必须为我们想象中的项目实现用户注册,并且我们将用简约的架构来实现这一点。 我们可以想出一个像这样的实体: package entity //User结构体 type User struct { email string password string name string dateOfBirth string } //业务级别的验证 func Validate() error { ... } 现在我们来创建一个用户注册的用例: package usecase import "entity" func RegisterUser(user entity.User) { //验证和保存用户逻辑 } 看起来我们需要一些基础设施模块来存储用户。 我们还没有在基础设施级别实现任何 UserRepository,我们还遇到了另一个问题,通过简洁的架构原则,更高级别的层无法知道低级别层的存在。 如何来解决这个问题? 不需要触及基础设施中的任何部分,我们会对我们的用例说,有某种用户保护程序可以帮助我们的用户注册。 package usecase import "entity" type UserSaver interface { Save(user entity.User) error } //UserRegisterUseCase 存储它的依赖关系 type UserRegisterUseCase struct { userSaver UserSaver } func newUserRegisterUseCase(userSaver UserSaver) UserRegisterUseCase { return &{userSaver} } func (u UserRegisterUseCase) RegisterUser(user entity.

阅读全文

最近体验了一下微信小程序开发,做了一个简单的刷猫片的小玩具,效果大致如下: 开始是用 Laravel 写了 API,后来又用 Go 的 Iris 写了一套,压测了一下,Iris 的性能比 Laravel 的高了可不是一点点,后来就换 Iris 版本的 API 了。数据通过 Go 写了个简单的脚本抓取入库,附件上传到七牛。 本来这个小程序还有小论坛和复制淘宝链接功能的,但是上传到微信审核以后死活不能通过审核,就阉割掉了,暂时就先放几个刷猫片的小模块玩玩吧。 说下体验开发微信小程序的感受吧: 上手不难,尤其是熟悉 Vue.js 这样的前端框架的话刷下文档就直接上手做了 API 还算丰富,而且开放的 API 越来越多,脑洞大一点可以做一些有趣的小程序 从微信小程序后台统计来看,果然是用完即走,而且走了就不回来了 …… 微信小程序还是略封闭,比如我的社区板块一直审核不通过,关键也不告诉具体未通过的原因,就说未经微信授权巴拉巴拉的 源码请戳这里: https://github.com/yuansir/youmaolu-weixin-app-api https://github.com/yuansir/youmaolu-weixin-app 体验请微信扫描: 之前搭建的一个撸猫社区(有猫撸)一直放着没搞了,有空得把注册重新写一下,邮箱激活还不支持中文名这种注册方式确实太蛋疼了。。。。 转载请注明: 转载自Ryan 是菜鸟 | LNMP 技术栈笔记 如果觉得本篇文章对您十分有益,何不 打赏一下 本文链接地址: 微信小程序【有猫撸】开发体验 本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可

阅读全文

Laravel 是我最喜欢的 PHP Web 开发框架,所以也希望可以在 Go 的 Web 框架中选择一个类似 Laravel 这样的好用又全栈的框架,刷了一下Beego, Echo , Gin, 以及Iris的文档,最终还是选择 Iris,当然我是没有从性能角度考虑,只是从可以快速开发,且支持的特性全还有就是看着顺眼的心理选择了 Iris,应该有不少 PHPer 像我一样使用 Laravel 同时在学习 Go,所以为了便于 Laravel 开发者可以快速的转到 Iris 开发,我准备写一系列这两者框架的比较文章。 基本路由 Iris 构建基本路由和 Laravel 的基本路由很像,都只需要一个 URI 与一个闭包: Laravel Route::get('foo', function () { return 'Hello World'; }); Iris app.Get("/foo", func(ctx iris.Context) { ctx.WriteString("Hello World") }) 可用的路由方法 Iris 和 Laravel 一样,能够响应任何的 HTTP 请求路由: Laravel Route::get($uri, $callback); Route::post($uri, $callback); Route::put($uri, $callback); Route::patch($uri, $callback); Route::delete($uri, $callback); Route::options($uri, $callback); Iris

阅读全文

作者的图片

Ryan是菜鸟 | LNMP技术栈笔记

一步一个脚印,一直在路上!记录LNMP技术栈,Web架构,区块链等笔记

菜鸟码农

南京