trpc-group / trpc-go

A pluggable, high-performance RPC framework written in golang
Other
742 stars 85 forks source link

affected/package: config.go #143

Closed Ashion closed 6 months ago

Ashion commented 6 months ago

What version of tRPC-Go are you using?

master

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env

What did you do?

I have service on both restful and trpc, and needs the restful listen on all addresses, trpc listen on localhost(127.0.0.1) it seems cannot work likes this.

  1. test the examples/features/restful
  2. update configure trpc_go.yaml to
    
    global:                             # global config.
    namespace: Development            # environment type, two types: production and development.
    env_name: test                    # environment name, names of multiple environments in informal settings.

server: # server configuration. app: test # business application name. server: helloworld # service process name. bin_path: /usr/local/trpc/bin/ # paths to binary executables and framework configuration files. conf_path: /usr/local/trpc/conf/ # paths to business configuration files. data_path: /usr/local/trpc/data/ # paths to business data files. service: # business service configuration,can have multiple.

plugins: # plugin configuration. log: # log configuration. default: # default log configuration, support multiple outputs.

4. update main.go to
 ``` go
package main

import (
    "context"
    "fmt"

    trpc "trpc.group/trpc-go/trpc-go"
    "trpc.group/trpc-go/trpc-go/examples/features/restful/pb"
    "trpc.group/trpc-go/trpc-go/log"
)

func main() {
    // init trpc server
    server := trpc.NewServer()
    // Register the greeter service with the server
    svc := new(greeterService)
    pb.RegisterGreeterService(server.Service("trpc.test.helloworld.Greeter"), svc)
    pb.RegisterGreeterService(server.Service("trpc.test.helloworld.Greeter1"), svc)
    // Run the server
    if err := server.Serve(); err != nil {
        log.Fatal(err)
    }
}

// greeterService is used to implement pb.GreeterService.
type greeterService struct {
    // unimplementedGreeterServiceServer is the unimplemented greeter service server
    pb.UnimplementedGreeter
}

// SayHello implements pb.GreeterService.
func (g greeterService) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
    log.InfoContextf(ctx, "[restful] Received SayHello request with req: %v", req)
    // handle request
    rsp := &pb.HelloReply{
        Message: "[restful] SayHello Hello " + req.Name,
    }
    return rsp, nil
}

// Message implements pb.GreeterService.
func (g greeterService) Message(ctx context.Context, req *pb.MessageRequest) (*pb.MessageInfo, error) {
    log.InfoContextf(ctx, "[restful] Received Message request with req: %v", req)
    // handle request
    rsp := &pb.MessageInfo{
        Message: fmt.Sprintf("[restful] Message name:%s,subfield:%s",
            req.GetName(), req.GetSub().GetSubfield()),
    }
    return rsp, nil
}

// UpdateMessage implements pb.GreeterService.
func (g greeterService) UpdateMessage(ctx context.Context, req *pb.UpdateMessageRequest) (*pb.MessageInfo, error) {
    log.InfoContextf(ctx, "[restful] Received UpdateMessage request with req: %v", req)
    // handle request
    rsp := &pb.MessageInfo{
        Message: fmt.Sprintf("[restful] UpdateMessage message_id:%s,message:%s",
            req.GetMessageId(), req.GetMessage().GetMessage()),
    }
    return rsp, nil
}

// UpdateMessageV2 implements pb.GreeterService.
func (g greeterService) UpdateMessageV2(ctx context.Context, req *pb.UpdateMessageV2Request) (*pb.MessageInfo, error) {
    log.InfoContextf(ctx, "[restful] Received UpdateMessageV2 request with req: %v", req)
    // handle request
    rsp := &pb.MessageInfo{
        Message: fmt.Sprintf("[restful] UpdateMessageV2 message_id:%s,message:%s",
            req.GetMessageId(), req.GetMessage()),
    }
    return rsp, nil
}

What did you expect to see?

trpc.test.helloworld.Greeter listen on :9092 trpc service:trpc.test.helloworld.Greeter1 listen on 127.0.0.1:9093

2023-12-11 21:11:51.967 DEBUG   maxprocs/maxprocs.go:47 maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined
2023-12-11 21:12:03.947 INFO    server/service.go:167   process:7755, restful service:trpc.test.helloworld.Greeter launch success, tcp::9092, serving ...
2023-12-11 21:12:03.947 INFO    server/service.go:167   process:7755, trpc service:trpc.test.helloworld.Greeter1 launch success, tcp:127.0.0.1:9093, serving ...

What did you see instead?

2023-12-11 21:11:51.967 DEBUG   maxprocs/maxprocs.go:47 maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined
2023-12-11 21:12:03.947 INFO    server/service.go:167   process:7755, restful service:trpc.test.helloworld.Greeter launch success, tcp:127.0.0.1:9092, serving ...
2023-12-11 21:12:03.947 INFO    server/service.go:167   process:7755, trpc service:trpc.test.helloworld.Greeter1 launch success, tcp:127.0.0.1:9093, serving ...
Ashion commented 6 months ago

it seems in config.go will set the ip to global local ip when the ip in configure is empty.

// RepairConfig repairs the Config by filling in some fields with default values.
func RepairConfig(cfg *Config) error {
    // nic -> ip
    if err := repairServiceIPWithNic(cfg); err != nil {
        return err
    }
    // set default read buffer size
    if cfg.Global.ReadBufferSize == nil {
        readerSize := codec.DefaultReaderSize
        cfg.Global.ReadBufferSize = &readerSize
    }
    codec.SetReaderSize(*cfg.Global.ReadBufferSize)

    // protocol network ip empty
    for _, serviceCfg := range cfg.Server.Service {
        setDefault(&serviceCfg.Protocol, cfg.Server.Protocol)
        setDefault(&serviceCfg.Network, cfg.Server.Network)
        setDefault(&serviceCfg.IP, cfg.Global.LocalIP)
        setDefault(&serviceCfg.Transport, cfg.Server.Transport)
        setDefault(&serviceCfg.Address, net.JoinHostPort(serviceCfg.IP, strconv.Itoa(int(serviceCfg.Port))))

        // server async mode by default
        if serviceCfg.ServerAsync == nil {
            enableServerAsync := true
            serviceCfg.ServerAsync = &enableServerAsync
        }
        // writev disabled by default
        if serviceCfg.Writev == nil {
            enableWritev := false
            serviceCfg.Writev = &enableWritev
        }
        if serviceCfg.Timeout == 0 {
            serviceCfg.Timeout = cfg.Server.Timeout
        }
        if serviceCfg.Idletime == 0 {
            serviceCfg.Idletime = defaultIdleTimeout
            if serviceCfg.Timeout > defaultIdleTimeout {
                serviceCfg.Idletime = serviceCfg.Timeout
            }
        }
    }

    setDefault(&cfg.Client.Namespace, cfg.Global.Namespace)
    for _, backendCfg := range cfg.Client.Service {
        repairClientConfig(backendCfg, &cfg.Client)
    }
    return nil
}
WineChord commented 6 months ago

Try explicitly setting 0.0.0.0:

      ip: 0.0.0.0
      port: 9092   
Ashion commented 6 months ago

so the unspecified "ip" not indicated that listen to all interface, it will choose lastest specified "ip" in service or local ip specified. it seems an uncertain operation, maybe it can mentioned in docs.

Try explicitly setting 0.0.0.0:

      ip: 0.0.0.0
      port: 9092