zoukankan      html  css  js  c++  java
  • 《gPRC使用protobuf构建微服务》阅读笔记

    首先我需要去了解一些概念,根据百度百科了解到:

    l  微服务架构:微服务架构是一项在云中部署应用和服务的新技术。微服务可以在“自己的程序”中运行,并通过“轻量级设备与HTTP型API进行沟通”。

    l  gPRC:gRPC 是一款高性能、开源的 RPC 框架,产自 Google,基于 ProtoBuf 序列化协议进行开发,支持多种语言。

    我们过去根据 MVC 划分目录结构,由Controller 层处理业务逻辑,Model 层作为对象实体类,对数据库进行 CURD操作,View 视图层处理数据渲染和页面交互。以及 MVP、MVVM 都是将整个项目的代码是集中在一个代码库中,进行业务处理。这种单一聚合代码的方式在前期实现业务的速度很快,但在后期会暴露很多问题:

    1. 开发与维护困难:随着业务复杂度的增加,代码的耦合度往往会变高,多个模块相互耦合后不易横向扩展

    2. 效率和可靠性低:过大的代码量将降低响应速度,应用潜在的安全问题也会累积

    微服务将一个大且聚合的业务项目拆解为多个小且独立的业务模块,每一模块即服务,各服务间使用高效的协议(protobuf、JSON 等)相互调用即是 RPC。这种拆分代码库的方式有以下特点:

    每个服务应作为小规模的、独立的业务模块在运行,类似 Unix 的 Do one thing and do it well

    每个服务应在进行自动化测试和(分布式)部署时,不影响其他服务

    每个服务内部进行细致的错误检查和处理,提高了健壮性

    本质上,二者只是聚合与拆分代码的方式不同。

    安装gRPC与protoc编译器:

    go get -u google.golang.org/grpc

    go get -u github.com/golang/protobuf/protoc-gen-go

    定义微服务的user.protoc文件

    syntax = "proto3";    // 指定语法格式,注意 proto3 不再支持 proto2 的 required 和 optional

    package proto;        // 指定生成的 user.pb.go 的包名,防止命名冲突

    // service 定义开放调用的服务,即 UserInfoService 微服务

    service UserInfoService {

        // rpc 定义服务内的 GetUserInfo 远程调用

        rpc GetUserInfo (UserRequest) returns (UserResponse) {

        }

    }

    // message 对应生成代码的 struct

    // 定义客户端请求的数据格式

    message UserRequest {

        // [修饰符] 类型 字段名 = 标识符;

        string name = 1;

    }

    // 定义服务端响应的数据格式

    message UserResponse {

        int32 id = 1;

        string name = 2;

        int32 age = 3;

    repeated string title = 4;    // repeated 修饰符表示字段是可变数组,即 slice 类型

    生成 user.pb.go

    package proto

    import (

        context "golang.org/x/net/context"

        grpc "google.golang.org/grpc"

    )

    // 请求结构

    type UserRequest struct {

        Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`

    }

    // 为字段自动生成的 Getter

    func (m *UserRequest) GetName() string {

        if m != nil {

            return m.Name

        }

        return ""

    }

    // 响应结构

    type UserResponse struct {

        Id    int32    `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`

        Name  string   `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`

        Age   int32    `protobuf:"varint,3,opt,name=age" json:"age,omitempty"`

        Title []string `protobuf:"bytes,4,rep,name=title" json:"title,omitempty"`

    }

    // ...

    // 客户端需实现的接口

    type UserInfoServiceClient interface {

        GetUserInfo(ctx context.Context, in *UserRequest, opts ...grpc.CallOption) (*UserResponse, error)

    }

    // 服务端需实现的接口

    type UserInfoServiceServer interface {

        GetUserInfo(context.Context, *UserRequest) (*UserResponse, error)

    }

    // 将微服务注册到 grpc

    func RegisterUserInfoServiceServer(s *grpc.Server, srv UserInfoServiceServer) {

        s.RegisterService(&_UserInfoService_serviceDesc, srv)

    }

    // 处理请求

    func _UserInfoService_GetUserInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {...}

  • 相关阅读:
    laravel的验证码
    laravel的中间件
    laravel的基本使用
    laravel的路由
    layui上传文件的choose只触发一次
    宝塔访问站点上一级目录
    orcale的几个查询
    tree的递归,适合与el-tree
    GIT 命令大全
    Oracle 时间戳与日期的转换
  • 原文地址:https://www.cnblogs.com/lzq666/p/11045316.html
Copyright © 2011-2022 走看看