精华内容
下载资源
问答
  • go 微服务

    2020-11-30 23:54:11
    Go 微服务 微服务概述 Soa 的一种实践,单一职责,原子进程,独立进程,隔离部署,去中心话的服务治理 Go 实施一个微服务 Kit:一个微服务的基础库 Service:业务代码+kit依赖+第三方依赖组成的业务微服务 Rpc+message...

    Go 微服务

    微服务概述
    Soa 的一种实践,单一职责,原子进程,独立进程,隔离部署,去中心话的服务治理

    Go 实施一个微服务
    Kit:一个微服务的基础库
    Service:业务代码+kit依赖+第三方依赖组成的业务微服务
    Rpc+message queque:轻量级通讯
    多个微服务完成了一个完整的用户场景

    去中心化
    数据去中心化
    治理去中心化
    技术去中心化
    每个服务独享自身的数据存储设施

    可用性,兼容性设计
    隔离
    超时控制
    负载保护
    限流
    降级
    重试
    负载均衡
    发送的数据要保守,接守数据要开放,保证兼容性

    微服务设计
    面向用户业务服务的apl

    Grpc 基于标准的http2设计,支持双向流,消息头压缩,单tcp的多用复用,服务端推送等

    展开全文
  • go微服务

    2020-01-14 15:53:56
    go微服务框架go-micro深度学习(一) 整体架构介绍 https://www.cnblogs.com/li-peng/p/9558421.html 微服务化项目除了稳定性我个人还比较关心的几个问题: 一: 服务间数据传输的效率和安全性。 二: 服务的动态...

    go微服务框架go-micro深度学习(一) 整体架构介绍

    https://www.cnblogs.com/li-peng/p/9558421.html

    微服务化项目除了稳定性我个人还比较关心的几个问题:

         一: 服务间数据传输的效率和安全性。

         二: 服务的动态扩充,也就是服务的注册和发现,服务集群化。

         三: 微服务功能的可订制化,因为并不是所有的功能都会很符合你的需求,难免需要根据自己的需要二次开发一些功能。

     

         go-micro是go语言下的一个很好的rpc微服务框架,功能很完善,而且我关心的几个问题也解决的很好:

         一:服务间传输格式为protobuf,效率上没的说,非常的快,也很安全。

         二:go-micro的服务注册和发现是多种多样的。我个人比较喜欢etcdv3的服务服务发现和注册。

         三:主要的功能都有相应的接口,只要实现相应的接口,就可以根据自己的需要订制插件。

         

         业余时间把go-micro的源码系统地读了一遍,越读越感觉这个框架写的好,从中也学到了很多东西。就想整理一系列的帖子,把学习go-micro的心得和大家分享。

    展开全文
  • 这是在新公司接触微服务框架(micro框架)后的总结,go微服务序列之一,在未来,我将会较深入的研究go和微服务,之后也会陆陆续续的发布一些文章,如果想直接查阅源码或者通过demo学习的,可以点击原文链接进入~如何...

    这是在新公司接触微服务框架(micro框架)后的总结,go微服务序列之一,在未来,我将会较深入的研究go和微服务,之后也会陆陆续续的发布一些文章,如果想直接查阅源码或者通过demo学习的,可以点击原文链接进入~

    如何编写一个微服务?这里用的是go的微服务框架go micro,具体的情况可以在github上查阅官方地址;

    这里给出的是开发一个微服务的步骤:

    1、书写proto文件,定义函数等
    具体实现:

    syntax = "proto3";package pb;service UserService {    
       //增
       rpc InsertUser (InsertUserReq) returns (InsertUserRep){}
       //删    rpc DeletetUser (DeletetUserReq) returns (DeletetUserRep){}
       //查rpc SelectUser(SelectUserReq)returns (SelectUserRep){}
       //改    rpc ModifyUser(ModifyUserReq)returns (ModifyUserRep){}
    }
    message User{
       int32 id = 1
    ;    string name = 2;    string Address = 3;    string Phone = 4;
    }message ModifyUserReq {    
       int32 id = 1 ;    string name = 2;    string Address = 3;    string Phone = 4;
    }message ModifyUserRep {
    }message SelectUserReq {    
       int32 id = 1 ;
    }message SelectUserRep {    
       User users
    = 1;
    }message DeletetUserReq {    
       int32 id = 1 ;
    }message DeletetUserRep {
       }message InsertUserReq {        int32 id = 1 ;    string name = 2;    string Address = 3;    string Phone = 4;
    }message InsertUserRep {        int32 id = 1 ;    string name = 2;    string Address = 3;    string Phone = 4;
    }

    2、采用代码生成工具生成user.pb.go文件,生成协议

    具体可以查看 https://github.com/micro/go-micro ,这里我自己写了个脚本文件 build_proto.sh ,自动将指定文件夹下的proto文件生成相应的协议,具体代码如下:

    #!/usr/bin/env bashprotoc --proto_path=./proto --go_out=plugins=micro:./src/share/pb ./proto/*.proto

    可以对代码进行自定义修改 … …. …

    运行 build_proto.sh 文件后可以看到在指定文件夹下生成了相应的 user.pb.go 文件,在我这里如:

    e767f15d0793345001fd99c92e4d80ff.png

    3、书写一个handler实现user.pb.go定义的接口

    具体实现:
    1)先创建一个user.go文件
    2)定义一个结构体,命名为UserHandler,实现user.proto文件所有定义的service,在这里要注意一点,即使是暂时没有实现好业务,也有给个空实现,代码如下:

    package handler
    import(    
       "mewe_job/GoMicroDemo/src/share/pb"
       "golang.org/x/net/context")
    type UserHandler struct {

    }
    // new一个UserHandlerfunc NewUserHandler() *UserHandler{    
       return &UserHandler{}
    }
    // 增func (c *UserHandler) InsertUser(ctx context.Context, req * pb.InsertUserReq,rsp *pb.InsertUserRep)error {    
       return nil}
    // 删func (c *UserHandler) DeletetUser(ctx context.Context, req * pb.DeletetUserReq,rsp *pb.DeletetUserRep)error {    
       return nil}
    // 查func (c *UserHandler) SelectUser(ctx context.Context, req * pb.SelectUserReq,rsp *pb.SelectUserRep)error {  
     return nil}
    //改func (c *UserHandler) ModifyUser(ctx context.Context, req * pb.ModifyUserReq,rsp *pb.ModifyUserRep)error {
       return nil}

    4、将handler注册进微服务,这一步在main中实现
    具体实现:

    package mainimport (    
       "github.com/micro/cli"
       "mewe_job/GoMicroDemo/src/share/pb"
       "github.com/micro/go-micro/server"
       "mewe_job/GoMicroDemo/src/user-srv/handler"
       "github.com/micro/go-micro"
       "log"
       "mewe_job/GoMicroDemo/src/user-srv/db"
       "mewe_job/GoMicroDemo/src/share/config")
    func main() {    
       // 创建Service,并定义一些参数
       service := micro.NewService(
           micro.Name("go.micro.srv.user"),
           micro.Version("latest"),
       )    
       // 定义Service动作操作
       service.Init(
           micro.Action(func(c *cli.Context) {
               log.Println("micro.Action test ...")            
               // 先注册db
               db.Init(config.MysqlDSN)
               pb.RegisterUserServiceHandler(service.Server(), handler.NewUserHandler(), server.InternalHandler(true))
           }),
           micro.AfterStop(func() error {
               log.Println("micro.AfterStop test ...")        
               return nil
           }),
           micro.AfterStart(func() error {
               log.Println("micro.AfterStart test ...")            
               return nil
           }),
       )

       log.Println("启动user-srv服务 ...")    
       //启动service
       if err := service.Run(); err != nil {
           log.Panic("user-srv服务启动失败 ...")
       }
    }

    这段代码主要的点有:

    • 创建service,通过以下代码可以初始化一个名叫 go.micro.srv.user 的微服务

          // 创建Service,并定义一些参数
         service := micro.NewService(
             micro.Name("go.micro.srv.user"),
             micro.Version("latest"),
         )
    • 注册db连接和给go.micro.srv.user这个微服务绑定handler,虽然目前我还没有在db中定义db层的操作

    db.Init(config.MysqlDSN)
               pb.RegisterUserServiceHandler(service.Server(), handler.NewUserHandler(), server.InternalHandler(true))
    • 启动service,通过Run开启

    if err := service.Run(); err != nil {
           log.Panic("user-srv服务启动失败 ...")
       }

    5、现在就可以通过 go run main.go —registry=mdns 启动该服务了,之所以携带 —registry=mdns 是因为我本地ubuntu系统没有安装consul实现服务发现,所以就采用了gomicro官方推荐的方法。

    6、到这一步客户端还无法访问到服务,需要做些处理,我这里是加了个web服务,再将客户端的请求进行转发,main函数实现如下:

    func main() {
       /*    方案一:
       mux := http.NewServeMux()
       mux.HandleFunc("/", handleRPC)
       log.Println("Listen on :8082")
       http.ListenAndServe(":8082", mux)
       */
       /*  方案二  */
       service := web.NewService(
           web.Name(config.ServicePrefix+".web"),
       )

       service.HandleFunc("/", handleRPC)    
       if err := service.Init(); err != nil {
           log.Fatal(err)
       }    if err := service.Run(); err != nil {
           log.Fatal(err)
       }
    }

    这里主要的函数是handleRPC这个函数,由于代码量偏多,具体实现可以查看源码。这里如果使用consul实现了服务发现,也可以通过方案一进行实现,这样的话web服务的端口还是固定的。

    7、开启web服务

    $ go run web.go --registry=mdns
    Listening on [::]:36859

    8、到这一步客户端就可以通过web服务端口和接口以及参数访问user这个微服务了,访问链接:(这里安利postman,一个谷歌的插件,超级好用 … )

    http://127.0.0.1:36859/user/selectUser

    tip:该项目的源码(包含数据库的增删查改的demo)可以查看原文链接~

    c7192ed27346e3a0ebbe3da7d669c20d.png

    展开全文
  • 基于微服务框架go-micro 封装的go微服务脚手架
  • Go微服务实战

    2018-10-08 15:24:57
    Go微服务实战,带色彩。需要的朋友可以拿去看看
  • 上一篇帖子《go微服务框架go-micro深度学习(一) 整体架构介绍》简单介绍了go-micro的整体框架结构,这一篇主要写go-micro使用方式的例子,中间会穿插一些go-micro的源码,和调用流程图,帮大家更好的理解go-micro的...

    上一篇帖子《go微服务框架go-micro深度学习(一) 整体架构介绍》简单介绍了go-micro的整体框架结构,这一篇主要写go-micro使用方式的例子,中间会穿插一些go-micro的源码,和调用流程图,帮大家更好的理解go-micro的底层。更详细更具体的调用流程和细节,会在以后的帖子里详细讲解。

    例子的github地址: gomicrorpc 跑一遍例子,也就会明白个大概。

    安装所需要的环境

    go-micro服务发现默认使用的是consul,

    brew install consulconsul agent -dev

    或者直接使用使用docker跑

    docker run -p 8300:8300 -p 8301:8301 -p 8301:8301/udp -p 8302:8302/udp -p 8302:8302 -p 8400:8400 -p 8500:8500 -p 53:53/udp consul

    我个人更喜欢etcdv3原因我上一篇也有提到过,gomicro服务发现不支持consul集群,我之前也写过etcdv3 集群的搭建和使用帖子,有时间大家可以看一下

    安装go-micro框架

    go get github.com/micro/go-micro

    安装protobuf和依赖 prtobuf的基础知识我这里就不讲了,如果不了解的可以看一下官方文档,就是一个跨平台,跨语言的数据序列化库,简单易学。

    是go-micro用于帮助我们生成服务接口和一系列的调用代码

    brew install protobufgo get -u -v github.com/golang/protobuf/{proto,protoc-gen-go}go get -u -v github.com/micro/protoc-gen-micro

    protobuf也可以直接从源码安装

    wget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-all-3.6.1.tar.gztar zxvf protobuf-all-3.6.1.tar.gzcd protobuf-3.6.1/./autogen.sh./configure makemake installprotoc -h

    安装micro工具包,这个安装是可选项,micro提供了一系列的工具来帮助我们更好的使用go-micro。

    go get github.com/micro/micro

    例子1

    创建proto文件common.proto,这个文件包含了传入和返回的参数,参数包含了常用的基础类型、数组、map等。还有一个Say 服务,这个服务里有一个rpc方法。

    syntax = "proto3";package model;message SayParam {    string msg = 1;}message Pair {    int32 key = 1;    string values = 2;}message SayResponse {    string msg = 1;    // 数组    repeated string values = 2;    // map    map header = 3;    RespType type = 4;}enum RespType {    NONE = 0;    ASCEND = 1;    DESCEND = 2;}// 服务接口service Say {    rpc Hello(SayParam) returns (SayResponse) {}}

    在根目录下运行,生成两个模板文件

      protoc --proto_path=$GOPATH/src:. --micro_out=. --go_out=. example1/proto/*.proto 

    一个文件是proto的go 结构文件,还有一个go-micro rpc的接口文件。

    3e3b3320dad3ba45565fb0eef6b91061.png

    server 端:

    type Say struct {}func (s *Say) Hello(ctx context.Context, req *model.SayParam, rsp *model.SayResponse) error {    fmt.Println("received", req.Msg)    rsp.Header = make(map[string]*model.Pair)    rsp.Header["name"] = &model.Pair{Key: 1, Values: "abc"}    rsp.Msg = "hello world"    rsp.Values = append(rsp.Values, "a", "b")    rsp.Type = model.RespType_DESCEND    return nil}func main() {    // 我这里用的etcd 做为服务发现,如果使用consul可以去掉    reg := etcdv3.NewRegistry(func(op *registry.Options){        op.Addrs = []string{            "http://192.168.3.34:2379", "http://192.168.3.18:2379", "http://192.168.3.110:2379",        }    })    // 初始化服务    service := micro.NewService(        micro.Name("lp.srv.eg1"),        micro.Registry(reg),    )    service.Init()    // 注册 Handler    model.RegisterSayHandler(service.Server(), new(Say))    // run server    if err := service.Run(); err != nil {        panic(err)    }}

    服务发现我使用的是etcdv3 替换了默认的consul

    micro.NewService 初始化服务,然后返回一个Service接口的实例,newService()方法的大概流程如下,

    5468b5a44496535ac5f5e96d081f548b.png

    先是给各个接口初始化默认值,再使用传入的值替换默认值,这也是go-micro可替换插件的地方。

    service有一个Init()可选方法,这是一个单例方法,

    func (s *service) Init(opts ...Option) {    // process options    for _, o := range opts {        o(&s.opts)    }    s.once.Do(func() {        // save user action        action := s.opts.Cmd.App().Action        // set service action        s.opts.Cmd.App().Action = func(c *cli.Context) {                .........//这里就不把代码全显示出来了                .........        }}

    用于始化cmd的一些信息

    service.Run()方法 调用流程

    c6f99a109f76054fb4ae12cd9a111959.png

    因为在初始化的时候没有指定端口,系统会自动分配一个端口号分给Server,并把这个server的信息注册到Register。

    BeferStart和AfterStart也都是可以自定义的

    client 端:

    func main() {    // 我这里用的etcd 做为服务发现,如果使用consul可以去掉    reg := etcdv3.NewRegistry(func(op *registry.Options){        op.Addrs = []string{            "http://192.168.3.34:2379", "http://192.168.3.18:2379", "http://192.168.3.110:2379",        }    })    // 初始化服务    service := micro.NewService(        micro.Registry(reg),    )    service.Init()    sayClent := model.NewSayService("lp.srv.eg1", service.Client())    rsp, err := sayClent.Hello(context.Background(), &model.SayParam{Msg: "hello server"})    if err != nil {        panic(err)    }    fmt.Println(rsp)}

    上面根据proto文件的生成的两个文件中有一个是rpc的接口文件,接口文件已经帮我们把调用方法的整个流程封装好了。

    只需要给出服务名称和licent就可以。然后调用Hello方法

    源码:

    func (c *sayService) Hello(ctx context.Context, in *SayParam, opts ...client.CallOption) (*SayResponse, error) {    req := c.c.NewRequest(c.name, "Say.Hello", in)    out := new(SayResponse)    err := c.c.Call(ctx, req, out, opts...)    if err != nil {        return nil, err    }    return out, nil}

    主要的流程里都在c.c.Call方法里。简单来说流程如下

    4dd74006fa3c816de662c31c58ea209a.png

    就是得到节点信息address,根据address去查询 pool里是否有连接,如果有则取出来,如果没有则创建,然后进行数据传输,传输完成后把client放回到pool内。pool的大小也是可以控制的,这部分的代码读起来特别爽,具体的细节和处理流程会在以后的帖子里详细讲解

    例子2

    例子1,做了一个简单的服务,已经不能再简单了,只是为了能让大家熟悉一下go-micro。看完例子1后应该会有更多的想法,想使用更多的go-micro的功能,比如protobuf生成的类都在一起,如果想model和api分开怎么处理,怎么使用go-micro的双向流,怎么使用消息推送,等等。所以我就双做了一个小例子,这个例子里包含了一些东西。

    2e586ef11f3f4c698cb318a5f13673c5.png

    这个例子我就只说一下组织结构,也没有多少代码,大家有时间看一下就ok了。

    proto下的两个文件夹,一个model一个rpcapi,是把数据和api分开,api引用了model

    看一下rpcapi

    syntax = "proto3";package rpcapi;import "github.com/lpxxn/gomicrorpc/example2/proto/model/common.proto";// 服务接口service Say {    rpc Hello(model.SayParam) returns (model.SayResponse) {}    rpc Stream(model.SRequest) returns (stream model.SResponse) {}}

    import了model里的common.proto

    在生成的时候一个只要go_out另一个只要micro_out就好了

      protoc --proto_path=$GOPATH/src:. --go_out=. example2/proto/model/*.proto     protoc --proto_path=$GOPATH/src:. --micro_out=. example2/proto/rpcapi/*.proto 

    订阅一个信息

        // Register Subscribers    if err := server.Subscribe(server.NewSubscriber(common.Topic1, subscriber.Handler)); err != nil {        panic(err)    }

    当有信息发送时,所有订阅了lp.srv.eg2.topic1这个信息的服务都会收到信息

    客户端发送信息

        p := micro.NewPublisher(common.Topic1, service.Client())    p.Publish(context.TODO(), &model.SayParam{Msg: lib.RandomStr(lib.Random(3, 10))})

    如果是生产环境一定不要用go-micro默认的信息发布和订阅处理方式,micro的插件plugin里是有很多成熟的插件。

    使用双向流的小功能

    这个方法只是每次向客户端发送一些数据,每次只发送一部分。比如我们给客户端推送的数据很大时,一次性全都推过去,是不太正确的做法,分批推送还是比较好的。

    func (s *Say) Stream(ctx context.Context, req *model.SRequest, stream rpcapi.Say_StreamStream) error {    for i := 0; i < int(req.Count); i++ {        rsp := &model.SResponse{}        for j := lib.Random(3, 5); j < 10; j++ {            rsp.Value = append(rsp.Value, lib.RandomStr(lib.Random(3, 10)))        }        if err := stream.Send(rsp); err != nil {            return err        }        // 模拟处理过程        time.Sleep(time.Microsecond * 50)    }    return nil    return nil}

    希望这个小例子能让大家入门go-micro.

    展开全文
  • 这次更新修复了旧框架中的所有主要问题,尽管它的的主要项目结构和接口都没有改变,具体改动内容请参见清晰架构(Clean Architecture)的Go微服务—重大升级。 现在它几乎拥有了我理想框架中的所有内容。它是一个轻...
  • 第二部分: Go微服务 - 构建我们的第一个服务 第二部分包含: 设置我们的Go工作空间。 构建我们第一个微服务。 通过HTTP使用Gorilla Web Toolkit来提供一些JSON服务。 介绍 虽然通过HTTP提供JSON服务不是内部服务和...
  • Go微服务架构的基石》.pdf 《Go微服务架构的基石》.pdf 《Go微服务架构的基石》.pdf
  • 作者:稀饭下雪链接:https://www.jianshu.com/p/9cb474dd451d来源:简书在前两篇系列博文中,我已经实现了user-srv、web-srv、api-srv,在新的一篇博文中,我要讲解的是如何在项目中...这里用的是go微服务框架...
  • go微服务框架go-micro

    2019-08-14 10:55:28
    go微服务框架go-micro深度学习(一) 整体架构介绍 https://blog.csdn.net/mi_duo/article/details/82701732 go 微服务micro基础搭建 https://blog.csdn.net/meiyouwsm/article/details/83090639 在kubernetes上...
  • Kratos是bilibili开源的一套Go微服务框架,包含大量微服务相关框架及工具。
  • Go微服务工具Gizmo.zip

    2019-07-16 02:53:07
    纽约时报开源的go微服务工具 提供如下特性标准化配置和日志可配置策略的状态监测端点用于管理 pprof 端点和日志级别的配置结构化日志,提供基本请求信息端点的有用度量优雅的停止服务定义期待和词汇的基本接口 ...
  • 【完整版9章】Go微服务入门到容器化实践,落地可观测的微服务电商项目,2021年新课 对于真正微服务项目来说,服务开发只是第一步,容器化、弹性伸缩和可观测才是真正关键。本课程将通过电商项目实战,系统学习完全...
  • Java微服务 vs Go微服务,究竟谁更强!?

    千次阅读 多人点赞 2021-01-13 08:33:00
    前言Java微服务能像Go微服务一样快吗?这是我最近一直在思索地一个问题。去年8月份的the Oracle Groundbreakers Tour 2020 LATAM大会上,Mark ...
  • 前言Java微服务能像Go微服务一样快吗?这是我最近一直在思索地一个问题。去年8月份的the Oracle Groundbreakers Tour 2020 LATAM大会上,Mark Nelson和Peter Nagy就对此做过一系列基础的的测试用以比较。接下来就给...
  • go微服务框架go-micro深度学习(一) 整体架构介绍 go微服务框架go-micro深度学习(二) 入门例子 go微服务框架go-micro深度学习(三) Registry服务的注册和发现 go微服务框架go-micro深度学习(四) rpc方法调用过程详解 ...
  • 前言Java微服务能像Go微服务一样快吗?这是我最近一直在思索地一个问题。去年8月份的the Oracle Groundbreakers Tour 2020 LATAM大会上,Mark Nelson和Peter Nagy就对此做过一系列基础的的测试用以比较。接下来就给...
  • 前言Java微服务能像Go微服务一样快吗?这是我最近一直在思索地一个问题。去年8月份的the Oracle Groundbreakers Tour 2020 LATAM大会上,Mark Nelson和Peter Nagy就对此做过一系列基础的的测试用以比较。接下来就给...
  • go 语言微服务实践原文链接 1024coder.com简介近一两年来,微服务架构已经成为热门话题(microservices.io),与传统的一体化应用架构相比,微服务架构在开发、测试、部署方面都有众多吸引人之处,越来越多没有历史...
  • 以上是Go微服务学习的架构图及核心知识点,非常推荐以下课程进行详细学习Go微服务,可以微信扫描进行学习
  • 前言Java微服务能像Go微服务一样快吗?这是我最近一直在思索地一个问题。去年8月份的the Oracle Groundbreakers Tour 2020 LATAM大会上,Mark Nelson和Peter Nagy就对此做过一系列基础的的测试用以比较。接下来就给...
  • Go 微服务框架 micro

    2021-01-08 05:33:20
    微服务是什么 微服务是一种架构风格,也是一些协同工作小而自治的服务 微服务的颗粒度比较小,一个大型软件应用由多个微服务组成 每种服务只做一件事,一种松耦合能够被独立开发和部署的无状态服务 我们怎么做的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,148
精华内容 1,259
关键字:

go微服务