RPC Implement & Call

    In a large system, there must be data transfer between multiple subsystems (services). If there is data transfer, you need a communication method. You can choose the simplest http for communication or rpc service for communication. In go-zero, we use zrpc to communicate between services, which is based on grpc.

    In the front, we have improved the interface protocol for user login, user query of books, etc., but the user did not do any user verification when querying the book. If the current user is a non-existent user, we do not allow him to view book information. From the above information, we can know that the user service needs to provide a method to obtain user information for use by the search service, so we need to create a user rpc service and provide a getUser method.

    • Compile the proto file

      1. package user;
      2. message IdReq{
      3. int64 id = 1;
      4. }
      5. message UserInfoReply{
      6. int64 id = 1;
      7. string name = 2;
      8. string number = 3;
      9. string gender = 4;
      10. }
      11. service user {
      12. rpc getUser(IdReq) returns(UserInfoReply);
      13. }
      • Generate rpc service code
        1. $ cd service/user/cmd/rpc
        2. $ goctl rpc proto -src user.proto -dir .
    • Add configuration and improve yaml configuration items

      1. $ vim service/user/cmd/rpc/internal/config/config.go
      1. type Config struct {
      2. zrpc.RpcServerConf
      3. Mysql struct {
      4. DataSource string
      5. }
      6. CacheRedis cache.CacheConf
      7. }
      1. $ vim /service/user/cmd/rpc/etc/user.yaml
      1. Name: user.rpc
      2. ListenOn: 127.0.0.1:8080
      3. Etcd:
      4. Hosts:
      5. - $etcdHost
      6. Key: user.rpc
      7. Mysql:
      8. CacheRedis:
      9. Pass: $pass
      10. Type: node
    • Add resource dependency

      1. $ vim service/user/cmd/rpc/internal/svc/servicecontext.go
    • Add rpc logic

      1. $ service/user/cmd/rpc/internal/logic/getuserlogic.go
      1. func (l *GetUserLogic) GetUser(in *user.IdReq) (*user.UserInfoReply, error) {
      2. one, err := l.svcCtx.UserModel.FindOne(in.Id)
      3. if err != nil {
      4. return nil, err
      5. }
      6. return &user.UserInfoReply{
      7. Id: one.Id,
      8. Name: one.Name,
      9. Number: one.Number,
      10. Gender: one.Gender,
      11. }, nil
      12. }

    Next we call user rpc in the search service

    • Add UserRpc configuration and yaml configuration items
      1. $ vim service/search/cmd/api/internal/config/config.go
      1. type Config struct {
      2. rest.RestConf
      3. Auth struct {
      4. AccessSecret string
      5. AccessExpire int64
      6. }
      7. UserRpc zrpc.RpcClientConf
      8. }
      1. $ vim service/search/cmd/api/etc/search-api.yaml
      1. Name: search-api
      2. Host: 0.0.0.0
      3. Port: 8889
      4. Auth:
      5. AccessSecret: $AccessSecret
      6. AccessExpire: $AccessExpire
      7. UserRpc:
      8. Etcd:
      9. Hosts:
      10. - $etcdHost
    • Add dependency

      1. Supplementary logic

        1. $ vim /service/search/cmd/api/internal/logic/searchlogic.go
        1. func (l *SearchLogic) Search(req types.SearchReq) (*types.SearchReply, error) {
        2. userIdNumber := json.Number(fmt.Sprintf("%v", l.ctx.Value("userId")))
        3. logx.Infof("userId: %s", userIdNumber)
        4. userId, err := userIdNumber.Int64()
        5. if err != nil {
        6. return nil, err
        7. }
        8. // use user rpc
        9. _, err = l.svcCtx.UserRpc.GetUser(l.ctx, &userclient.IdReq{
        10. Id: userId,
        11. })
        12. if err != nil {
        13. return nil, err
        14. }
        15. return &types.SearchReply{
        16. Name: req.Name,
        17. Count: 100,
        18. }, nil
        19. }
      2. Start etcd, redis, mysql
      3. Start user rpc
        1. $ cd /service/user/cmd/rpc
        2. $ go run user.go -f etc/user.yaml
        1. Starting rpc server at 127.0.0.1:8080...
      4. Start search api

        1. $ cd service/search/cmd/api
        2. $ go run search.go -f etc/search-api.yaml
      5. Verification Service

        1. $ curl -i -X GET \
        2. 'http://127.0.0.1:8889/search/do?name=%E8%A5%BF%E6%B8%B8%E8%AE%B0' \
        3. -H 'authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MTI4NjcwNzQsImlhdCI6MTYxMjc4MDY3NCwidXNlcklkIjoxfQ.JKa83g9BlEW84IiCXFGwP2aSd0xF3tMnxrOzVebbt80'
        1. HTTP/1.1 200 OK
        2. Content
        3. -Type: application/json
        4. Date: Tue, 09 Feb 2021 06:05:52 GMT
        5. Content-Length: 32
        6. {"name":"xiyouji","count":100}

      Guess you wants