Repository: go-kratos/kratos
Pull request #2741 (2023-03-17 09:40:19)

refactor(transport): format import and init slice cap
<!--
🎉 Thanks for sending a pull request to Kratos! Here are some tips for you:

1. If this is your first time contributing to Kratos, please read our contribution guide: https://go-kratos.dev/en/docs/community/contribution/
2. Ensure you have added or ran the appropriate tests and lint for your PR, please use `make lint` and `make test` before filing your PR, use `make clean` to tidy your go mod.
3. If the PR is unfinished, you may need to mark it as a WIP(Work In Progress) PR or Draft PR
4. Please use a semantic commits format title, such as `<type>[optional scope]: <description>`, see: https://go-kratos.dev/docs/community/contribution#type
5. at the same time, please note that similar work should be submitted in one PR as far as possible to reduce the workload of reviewers. Do not split a work into multiple PR unless it should.
-->

<!--
🎉 感谢您向 Kratos 发送 PR！以下是一些提示：
如果这是你第一次为 Kratos 贡献，请阅读我们的贡献指南：https://go-kratos.dev/en/docs/community/contribution/
2、确保您已经为您的 PR 添加或运行了适当的测试和lint，请在提交PR之前使用“make lint”和“make test”，使用“make clean”整理您的 go.mod。
3、如果 PR 未完成，您可能需要将其标记为 WIP（Work In Progress）PR 或 Draft PR
4、请使用语义提交格式标题，如“<类型>[可选范围]：<说明>`，请参阅：https://go-kratos.dev/docs/community/contribution#type
5. 同时请注意，同类的工作请尽量在一个PR中提交，以减轻 review 者的工作负担，不要把一项工作拆分成很多个PR，除非它应该这样做。
-->


#### Description (what this PR does / why we need it):
<img width="937" alt="image" src="https://user-images.githubusercontent.com/27986239/225868608-18f2e37a-b17b-46f1-ae5d-1dbefdef69e8.png">


#### Which issue(s) this PR fixes (resolves / be part of):
<!--
* Automatically closes linked issue when PR is merged.
* If your PR is not fully resolved the issue, please use `part of #<issue number>` instead.

Usage: `fixes/resolves #<issue number>`, or `fixes/resolves (paste link of issue)`.
-->


#### Other special notes for the reviewers:
<!--
* Somethings that need extra attention for the reviewers
* Some additional notes, TODO list, etc.
-->


codecov-commenter: ## [Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) Report
> Merging [#2741](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (329a65b) into [main](https://codecov.io/gh/go-kratos/kratos/commit/0c2d2632ac9d2340cbd57078ff0cdd82d534e322?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (0c2d263) will **increase** coverage by `0.04%`.
> The diff coverage is `87.50%`.

> :exclamation: Current head 329a65b differs from pull request most recent head 60f7b05. Consider uploading reports for the commit 60f7b05 to get more accurate results

:mega: This organization is not using Codecov’s [GitHub App Integration](https://github.com/apps/codecov). We recommend you install it so Codecov can continue to function properly for your repositories. [Learn more](https://about.codecov.io/blog/codecov-is-updating-its-github-integration/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos)

```diff
@@            Coverage Diff             @@
##             main    #2741      +/-   ##
==========================================
+ Coverage   84.74%   84.78%   +0.04%     
==========================================
  Files          88       88              
  Lines        3893     3897       +4     
==========================================
+ Hits         3299     3304       +5     
+ Misses        419      418       -1     
  Partials      175      175              
```


| [Impacted Files](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) | Coverage Δ | |
|---|---|---|
| [transport/grpc/client.go](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2dycGMvY2xpZW50Lmdv) | `83.62% <ø> (ø)` | |
| [transport/grpc/resolver/discovery/builder.go](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2dycGMvcmVzb2x2ZXIvZGlzY292ZXJ5L2J1aWxkZXIuZ28=) | `90.00% <ø> (ø)` | |
| [transport/grpc/server.go](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2dycGMvc2VydmVyLmdv) | `83.83% <ø> (ø)` | |
| [transport/http/binding/bind.go](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2h0dHAvYmluZGluZy9iaW5kLmdv) | `100.00% <ø> (ø)` | |
| [transport/http/codec.go](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2h0dHAvY29kZWMuZ28=) | `60.37% <ø> (ø)` | |
| [transport/http/server.go](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2h0dHAvc2VydmVyLmdv) | `74.50% <ø> (ø)` | |
| [transport/grpc/resolver/discovery/resolver.go](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2dycGMvcmVzb2x2ZXIvZGlzY292ZXJ5L3Jlc29sdmVyLmdv) | `68.25% <83.33%> (+4.46%)` | :arrow_up: |
| [transport/http/binding/encode.go](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2h0dHAvYmluZGluZy9lbmNvZGUuZ28=) | `100.00% <100.00%> (ø)` | |
| [transport/http/resolver.go](https://codecov.io/gh/go-kratos/kratos/pull/2741?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-dHJhbnNwb3J0L2h0dHAvcmVzb2x2ZXIuZ28=) | `96.34% <100.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos)

demoManito: please merge https://github.com/go-kratos/kratos/pull/2748, skip linter unused-parameter check. @shenqidebaozi @haiyux 

Patch:
diff --git a/.golangci.yml b/.golangci.yml
index 06ee200c..1408787e 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -68,4 +68,4 @@ linters-settings:
     # recommend 10-20
     min-complexity: 50
   goimports:
-    local-prefixes: github.com/go-kratos/kratos # Put imports beginning with prefix after 3rd-party packages
+    local-prefixes: github.com/go-kratos # Put imports beginning with prefix after 3rd-party packages
diff --git a/cmd/kratos/internal/base/path.go b/cmd/kratos/internal/base/path.go
index 7456ba67..d24647fd 100644
--- a/cmd/kratos/internal/base/path.go
+++ b/cmd/kratos/internal/base/path.go
@@ -5,7 +5,6 @@ import (
 	"fmt"
 	"log"
 	"os"
-	"path"
 	"path/filepath"
 	"strings"
 
@@ -17,7 +16,7 @@ func kratosHome() string {
 	if err != nil {
 		log.Fatal(err)
 	}
-	home := path.Join(dir, ".kratos")
+	home := filepath.Join(dir, ".kratos")
 	if _, err := os.Stat(home); os.IsNotExist(err) {
 		if err := os.MkdirAll(home, 0o700); err != nil {
 			log.Fatal(err)
@@ -27,7 +26,7 @@ func kratosHome() string {
 }
 
 func kratosHomeWithDir(dir string) string {
-	home := path.Join(kratosHome(), dir)
+	home := filepath.Join(kratosHome(), dir)
 	if _, err := os.Stat(home); os.IsNotExist(err) {
 		if err := os.MkdirAll(home, 0o700); err != nil {
 			log.Fatal(err)
@@ -75,8 +74,8 @@ func copyDir(src, dst string, replaces, ignores []string) error {
 		if hasSets(fd.Name(), ignores) {
 			continue
 		}
-		srcfp := path.Join(src, fd.Name())
-		dstfp := path.Join(dst, fd.Name())
+		srcfp := filepath.Join(src, fd.Name())
+		dstfp := filepath.Join(dst, fd.Name())
 		var e error
 		if fd.IsDir() {
 			e = copyDir(srcfp, dstfp, replaces, ignores)
diff --git a/cmd/kratos/internal/base/repo.go b/cmd/kratos/internal/base/repo.go
index 4ad241c8..fe1ba18e 100644
--- a/cmd/kratos/internal/base/repo.go
+++ b/cmd/kratos/internal/base/repo.go
@@ -7,6 +7,7 @@ import (
 	"os"
 	"os/exec"
 	"path"
+	"path/filepath"
 	"strings"
 )
 
@@ -104,7 +105,7 @@ func (r *Repo) CopyTo(ctx context.Context, to string, modPath string, ignores []
 	if err := r.Clone(ctx); err != nil {
 		return err
 	}
-	mod, err := ModulePath(path.Join(r.Path(), "go.mod"))
+	mod, err := ModulePath(filepath.Join(r.Path(), "go.mod"))
 	if err != nil {
 		return err
 	}
@@ -116,7 +117,7 @@ func (r *Repo) CopyToV2(ctx context.Context, to string, modPath string, ignores,
 	if err := r.Clone(ctx); err != nil {
 		return err
 	}
-	mod, err := ModulePath(path.Join(r.Path(), "go.mod"))
+	mod, err := ModulePath(filepath.Join(r.Path(), "go.mod"))
 	if err != nil {
 		return err
 	}
diff --git a/cmd/kratos/internal/project/add.go b/cmd/kratos/internal/project/add.go
index 72a89f29..df5eff11 100644
--- a/cmd/kratos/internal/project/add.go
+++ b/cmd/kratos/internal/project/add.go
@@ -4,7 +4,7 @@ import (
 	"context"
 	"fmt"
 	"os"
-	"path"
+	"path/filepath"
 
 	"github.com/AlecAivazis/survey/v2"
 	"github.com/fatih/color"
@@ -17,7 +17,7 @@ var repoAddIgnores = []string{
 }
 
 func (p *Project) Add(ctx context.Context, dir string, layout string, branch string, mod string) error {
-	to := path.Join(dir, p.Name)
+	to := filepath.Join(dir, p.Name)
 
 	if _, err := os.Stat(to); !os.IsNotExist(err) {
 		fmt.Printf("🚫 %s already exists\n", p.Name)
@@ -40,13 +40,13 @@ func (p *Project) Add(ctx context.Context, dir string, layout string, branch str
 
 	repo := base.NewRepo(layout, branch)
 
-	if err := repo.CopyToV2(ctx, to, path.Join(mod, p.Path), repoAddIgnores, []string{path.Join(p.Path, "api"), "api"}); err != nil {
+	if err := repo.CopyToV2(ctx, to, filepath.Join(mod, p.Path), repoAddIgnores, []string{filepath.Join(p.Path, "api"), "api"}); err != nil {
 		return err
 	}
 
 	e := os.Rename(
-		path.Join(to, "cmd", "server"),
-		path.Join(to, "cmd", p.Name),
+		filepath.Join(to, "cmd", "server"),
+		filepath.Join(to, "cmd", p.Name),
 	)
 	if e != nil {
 		return e
diff --git a/cmd/kratos/internal/project/new.go b/cmd/kratos/internal/project/new.go
index c084e7f0..73c01986 100644
--- a/cmd/kratos/internal/project/new.go
+++ b/cmd/kratos/internal/project/new.go
@@ -4,7 +4,7 @@ import (
 	"context"
 	"fmt"
 	"os"
-	"path"
+	"path/filepath"
 
 	"github.com/AlecAivazis/survey/v2"
 	"github.com/fatih/color"
@@ -20,7 +20,7 @@ type Project struct {
 
 // New new a project from remote repo.
 func (p *Project) New(ctx context.Context, dir string, layout string, branch string) error {
-	to := path.Join(dir, p.Name)
+	to := filepath.Join(dir, p.Name)
 	if _, err := os.Stat(to); !os.IsNotExist(err) {
 		fmt.Printf("🚫 %s already exists\n", p.Name)
 		prompt := &survey.Confirm{
@@ -43,8 +43,8 @@ func (p *Project) New(ctx context.Context, dir string, layout string, branch str
 		return err
 	}
 	e := os.Rename(
-		path.Join(to, "cmd", "server"),
-		path.Join(to, "cmd", p.Name),
+		filepath.Join(to, "cmd", "server"),
+		filepath.Join(to, "cmd", p.Name),
 	)
 	if e != nil {
 		return e
diff --git a/cmd/kratos/internal/project/project.go b/cmd/kratos/internal/project/project.go
index f1f2cea0..fffa0fdc 100644
--- a/cmd/kratos/internal/project/project.go
+++ b/cmd/kratos/internal/project/project.go
@@ -5,7 +5,6 @@ import (
 	"errors"
 	"fmt"
 	"os"
-	"path"
 	"path/filepath"
 	"strings"
 	"time"
@@ -80,7 +79,7 @@ func run(_ *cobra.Command, args []string) {
 			return
 		}
 
-		mod, e := base.ModulePath(path.Join(projectRoot, "go.mod"))
+		mod, e := base.ModulePath(filepath.Join(projectRoot, "go.mod"))
 		if e != nil {
 			panic(e)
 		}
@@ -136,6 +135,6 @@ func getgomodProjectRoot(dir string) string {
 }
 
 func gomodIsNotExistIn(dir string) bool {
-	_, e := os.Stat(path.Join(dir, "go.mod"))
+	_, e := os.Stat(filepath.Join(dir, "go.mod"))
 	return os.IsNotExist(e)
 }
diff --git a/cmd/kratos/internal/proto/add/proto.go b/cmd/kratos/internal/proto/add/proto.go
index 8c716dc6..88184a28 100644
--- a/cmd/kratos/internal/proto/add/proto.go
+++ b/cmd/kratos/internal/proto/add/proto.go
@@ -3,7 +3,7 @@ package add
 import (
 	"fmt"
 	"os"
-	"path"
+	"path/filepath"
 )
 
 // Proto is a proto generator.
@@ -26,13 +26,13 @@ func (p *Proto) Generate() error {
 	if err != nil {
 		panic(err)
 	}
-	to := path.Join(wd, p.Path)
+	to := filepath.Join(wd, p.Path)
 	if _, err := os.Stat(to); os.IsNotExist(err) {
 		if err := os.MkdirAll(to, 0o700); err != nil {
 			return err
 		}
 	}
-	name := path.Join(to, p.Name)
+	name := filepath.Join(to, p.Name)
 	if _, err := os.Stat(name); !os.IsNotExist(err) {
 		return fmt.Errorf("%s already exists", p.Name)
 	}
diff --git a/cmd/kratos/internal/proto/server/server.go b/cmd/kratos/internal/proto/server/server.go
index 41fb9ee7..8a30d93c 100644
--- a/cmd/kratos/internal/proto/server/server.go
+++ b/cmd/kratos/internal/proto/server/server.go
@@ -4,7 +4,7 @@ import (
 	"fmt"
 	"log"
 	"os"
-	"path"
+	"path/filepath"
 	"strings"
 
 	"github.com/emicklei/proto"
@@ -16,8 +16,8 @@ import (
 // CmdServer the service command.
 var CmdServer = &cobra.Command{
 	Use:   "server",
-	Short: "Generate the proto Server implementations",
-	Long:  "Generate the proto Server implementations. Example: kratos proto server api/xxx.proto --target-dir=internal/service",
+	Short: "Generate the proto server implementations",
+	Long:  "Generate the proto server implementations. Example: kratos proto server api/xxx.proto --target-dir=internal/service",
 	Run:   run,
 }
 var targetDir string
@@ -64,8 +64,8 @@ func run(_ *cobra.Command, args []string) {
 					continue
 				}
 				cs.Methods = append(cs.Methods, &Method{
-					Service: serviceName(s.Name), Name: serviceName(r.Name), Request: r.RequestType,
-					Reply: r.ReturnsType, Type: getMethodType(r.StreamsRequest, r.StreamsReturns),
+					Service: serviceName(s.Name), Name: serviceName(r.Name), Request: parametersName(r.RequestType),
+					Reply: parametersName(r.ReturnsType), Type: getMethodType(r.StreamsRequest, r.StreamsReturns),
 				})
 			}
 			res = append(res, cs)
@@ -76,7 +76,7 @@ func run(_ *cobra.Command, args []string) {
 		return
 	}
 	for _, s := range res {
-		to := path.Join(targetDir, strings.ToLower(s.Service)+".go")
+		to := filepath.Join(targetDir, strings.ToLower(s.Service)+".go")
 		if _, err := os.Stat(to); !os.IsNotExist(err) {
 			fmt.Fprintf(os.Stderr, "%s already exists: %s\n", s.Service, to)
 			continue
@@ -105,6 +105,10 @@ func getMethodType(streamsRequest, streamsReturns bool) MethodType {
 	return unaryType
 }
 
+func parametersName(name string) string {
+	return strings.ReplaceAll(name, ".", "_")
+}
+
 func serviceName(name string) string {
 	return toUpperCamelCase(strings.Split(name, ".")[0])
 }
diff --git a/cmd/kratos/internal/run/run.go b/cmd/kratos/internal/run/run.go
index 005c832a..2def97a1 100644
--- a/cmd/kratos/internal/run/run.go
+++ b/cmd/kratos/internal/run/run.go
@@ -4,7 +4,6 @@ import (
 	"fmt"
 	"os"
 	"os/exec"
-	"path"
 	"path/filepath"
 	"strings"
 
@@ -108,7 +107,7 @@ func findCMD(base string) (map[string]string, error) {
 				}
 				for _, fileInfo := range paths {
 					if fileInfo.IsDir() {
-						abs := path.Join(walkPath, fileInfo.Name())
+						abs := filepath.Join(walkPath, fileInfo.Name())
 						cmdPath[strings.TrimPrefix(abs, wd)] = abs
 					}
 				}
diff --git a/contrib/opensergo/opensergo.go b/contrib/opensergo/opensergo.go
index e8f38c7b..56de2536 100644
--- a/contrib/opensergo/opensergo.go
+++ b/contrib/opensergo/opensergo.go
@@ -9,8 +9,6 @@ import (
 	"strconv"
 	"time"
 
-	"github.com/go-kratos/kratos/v2"
-
 	v1 "github.com/opensergo/opensergo-go/proto/service_contract/v1"
 	"golang.org/x/net/context"
 	"google.golang.org/genproto/googleapis/api/annotations"
@@ -19,6 +17,8 @@ import (
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/reflect/protoreflect"
 	"google.golang.org/protobuf/reflect/protoregistry"
+
+	"github.com/go-kratos/kratos/v2"
 )
 
 type Option func(*options)
diff --git a/contrib/registry/servicecomb/registry.go b/contrib/registry/servicecomb/registry.go
index 3e2a0e9f..d2e9a853 100644
--- a/contrib/registry/servicecomb/registry.go
+++ b/contrib/registry/servicecomb/registry.go
@@ -124,9 +124,6 @@ func (r *Registry) Register(_ context.Context, svcIns *registry.ServiceInstance)
 		// 保存当前版本微服务对应的sid
 		curServiceID = sid
 	}
-	props := make(map[string]string)
-	props[appIDKey] = appID
-	props[envKey] = env
 	if svcIns.ID == "" {
 		var id uuid.UUID
 		id, err = uuid.NewV4()
@@ -135,6 +132,10 @@ func (r *Registry) Register(_ context.Context, svcIns *registry.ServiceInstance)
 		}
 		svcIns.ID = id.String()
 	}
+	props := map[string]string{
+		appIDKey: appID,
+		envKey:   env,
+	}
 	_, err = r.cli.RegisterMicroServiceInstance(&discovery.MicroServiceInstance{
 		InstanceId: svcIns.ID,
 		ServiceId:  sid,
@@ -146,9 +147,9 @@ func (r *Registry) Register(_ context.Context, svcIns *registry.ServiceInstance)
 	if err != nil {
 		return err
 	}
-	ticker := time.NewTicker(30 * time.Second)
-	defer ticker.Stop()
 	go func() {
+		ticker := time.NewTicker(30 * time.Second)
+		defer ticker.Stop()
 		for {
 			<-ticker.C
 			_, err = r.cli.Heartbeat(sid, svcIns.ID)
diff --git a/contrib/registry/servicecomb/watcher.go b/contrib/registry/servicecomb/watcher.go
index b1f4fccf..cc4545cc 100644
--- a/contrib/registry/servicecomb/watcher.go
+++ b/contrib/registry/servicecomb/watcher.go
@@ -1,8 +1,9 @@
 package servicecomb
 
 import (
+	"context"
+
 	"github.com/go-chassis/sc-client"
-	"golang.org/x/net/context"
 
 	"github.com/go-kratos/kratos/v2/registry"
 )
diff --git a/selector/p2c/p2c.go b/selector/p2c/p2c.go
index 1d0ef8c5..afca9807 100644
--- a/selector/p2c/p2c.go
+++ b/selector/p2c/p2c.go
@@ -13,16 +13,16 @@ import (
 
 const (
 	forcePick = time.Second * 3
-	// Name is balancer name
+	// Name is p2c(Pick of 2 choices) balancer name
 	Name = "p2c"
 )
 
 var _ selector.Balancer = (*Balancer)(nil)
 
-// Option is random builder option.
+// Option is p2c builder option.
 type Option func(o *options)
 
-// options is random builder options
+// options is p2c builder options
 type options struct{}
 
 // New creates a p2c selector.
diff --git a/selector/wrr/wrr.go b/selector/wrr/wrr.go
index 3d91d62e..f81d7171 100644
--- a/selector/wrr/wrr.go
+++ b/selector/wrr/wrr.go
@@ -9,19 +9,19 @@ import (
 )
 
 const (
-	// Name is wrr balancer name
+	// Name is wrr(Weighted Round Robin) balancer name
 	Name = "wrr"
 )
 
 var _ selector.Balancer = (*Balancer)(nil) // Name is balancer name
 
-// Option is random builder option.
+// Option is wrr builder option.
 type Option func(o *options)
 
-// options is random builder options
+// options is wrr builder options
 type options struct{}
 
-// Balancer is a random balancer.
+// Balancer is a wrr balancer.
 type Balancer struct {
 	mu            sync.Mutex
 	currentWeight map[string]float64
diff --git a/transport/grpc/client.go b/transport/grpc/client.go
index a7a00910..3c8a17d7 100644
--- a/transport/grpc/client.go
+++ b/transport/grpc/client.go
@@ -6,6 +6,11 @@ import (
 	"fmt"
 	"time"
 
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials"
+	grpcinsecure "google.golang.org/grpc/credentials/insecure"
+	grpcmd "google.golang.org/grpc/metadata"
+
 	"github.com/go-kratos/kratos/v2/log"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/registry"
@@ -16,11 +21,6 @@ import (
 
 	// init resolver
 	_ "github.com/go-kratos/kratos/v2/transport/grpc/resolver/direct"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/credentials"
-	grpcinsecure "google.golang.org/grpc/credentials/insecure"
-	grpcmd "google.golang.org/grpc/metadata"
 )
 
 func init() {
diff --git a/transport/grpc/resolver/discovery/builder.go b/transport/grpc/resolver/discovery/builder.go
index 28aff384..3d147cd8 100644
--- a/transport/grpc/resolver/discovery/builder.go
+++ b/transport/grpc/resolver/discovery/builder.go
@@ -6,10 +6,10 @@ import (
 	"strings"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
-
 	"github.com/google/uuid"
 	"google.golang.org/grpc/resolver"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 const name = "discovery"
diff --git a/transport/grpc/resolver/discovery/resolver.go b/transport/grpc/resolver/discovery/resolver.go
index 03c76664..10775d74 100644
--- a/transport/grpc/resolver/discovery/resolver.go
+++ b/transport/grpc/resolver/discovery/resolver.go
@@ -6,13 +6,13 @@ import (
 	"errors"
 	"time"
 
+	"google.golang.org/grpc/attributes"
+	"google.golang.org/grpc/resolver"
+
+	"github.com/go-kratos/aegis/subset"
 	"github.com/go-kratos/kratos/v2/internal/endpoint"
 	"github.com/go-kratos/kratos/v2/log"
 	"github.com/go-kratos/kratos/v2/registry"
-
-	"github.com/go-kratos/aegis/subset"
-	"google.golang.org/grpc/attributes"
-	"google.golang.org/grpc/resolver"
 )
 
 type discoveryResolver struct {
@@ -49,9 +49,10 @@ func (r *discoveryResolver) watch() {
 }
 
 func (r *discoveryResolver) update(ins []*registry.ServiceInstance) {
-	addrs := make([]resolver.Address, 0)
-	endpoints := make(map[string]struct{})
-	filtered := make([]*registry.ServiceInstance, 0, len(ins))
+	var (
+		endpoints = make(map[string]struct{})
+		filtered  = make([]*registry.ServiceInstance, 0, len(ins))
+	)
 	for _, in := range ins {
 		ept, err := endpoint.ParseEndpoint(in.Endpoints, endpoint.Scheme("grpc", !r.insecure))
 		if err != nil {
@@ -70,15 +71,16 @@ func (r *discoveryResolver) update(ins []*registry.ServiceInstance) {
 	if r.subsetSize != 0 {
 		filtered = subset.Subset(r.selecterKey, filtered, r.subsetSize)
 	}
+
+	addrs := make([]resolver.Address, 0, len(filtered))
 	for _, in := range filtered {
 		ept, _ := endpoint.ParseEndpoint(in.Endpoints, endpoint.Scheme("grpc", !r.insecure))
 		endpoints[ept] = struct{}{}
 		addr := resolver.Address{
 			ServerName: in.Name,
-			Attributes: parseAttributes(in.Metadata),
+			Attributes: parseAttributes(in.Metadata).WithValue("rawServiceInstance", in),
 			Addr:       ept,
 		}
-		addr.Attributes = addr.Attributes.WithValue("rawServiceInstance", in)
 		addrs = append(addrs, addr)
 	}
 	if len(addrs) == 0 {
@@ -89,7 +91,6 @@ func (r *discoveryResolver) update(ins []*registry.ServiceInstance) {
 	if err != nil {
 		log.Errorf("[resolver] failed to update state: %s", err)
 	}
-
 	if r.debugLog {
 		b, _ := json.Marshal(filtered)
 		log.Infof("[resolver] update instances: %s", b)
diff --git a/transport/grpc/server.go b/transport/grpc/server.go
index 9a8344bf..6e281b67 100644
--- a/transport/grpc/server.go
+++ b/transport/grpc/server.go
@@ -7,22 +7,20 @@ import (
 	"net/url"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/internal/endpoint"
-	"github.com/go-kratos/kratos/v2/internal/matcher"
-
-	apimd "github.com/go-kratos/kratos/v2/api/metadata"
-
-	"github.com/go-kratos/kratos/v2/internal/host"
-	"github.com/go-kratos/kratos/v2/log"
-	"github.com/go-kratos/kratos/v2/middleware"
-	"github.com/go-kratos/kratos/v2/transport"
-
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/admin"
 	"google.golang.org/grpc/credentials"
 	"google.golang.org/grpc/health"
 	"google.golang.org/grpc/health/grpc_health_v1"
 	"google.golang.org/grpc/reflection"
+
+	apimd "github.com/go-kratos/kratos/v2/api/metadata"
+	"github.com/go-kratos/kratos/v2/internal/endpoint"
+	"github.com/go-kratos/kratos/v2/internal/host"
+	"github.com/go-kratos/kratos/v2/internal/matcher"
+	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/middleware"
+	"github.com/go-kratos/kratos/v2/transport"
 )
 
 var (
diff --git a/transport/http/binding/bind.go b/transport/http/binding/bind.go
index 10007367..69534ada 100644
--- a/transport/http/binding/bind.go
+++ b/transport/http/binding/bind.go
@@ -4,10 +4,9 @@ import (
 	"net/http"
 	"net/url"
 
-	"github.com/go-kratos/kratos/v2/errors"
-
 	"github.com/go-kratos/kratos/v2/encoding"
 	"github.com/go-kratos/kratos/v2/encoding/form"
+	"github.com/go-kratos/kratos/v2/errors"
 )
 
 // BindQuery bind vars parameters to target.
diff --git a/transport/http/binding/encode.go b/transport/http/binding/encode.go
index 72afd508..5f12cf37 100644
--- a/transport/http/binding/encode.go
+++ b/transport/http/binding/encode.go
@@ -20,13 +20,12 @@ func EncodeURL(pathTemplate string, msg interface{}, needQuery bool) string {
 	pathParams := make(map[string]struct{})
 	path := reg.ReplaceAllStringFunc(pathTemplate, func(in string) string {
 		// it's unreachable because the reg means that must have more than one char in {}
-		//if len(in) < 4 { //nolint:gomnd // **  explain the 4 number here :-) **
+		// if len(in) < 4 { //nolint:gomnd // **  explain the 4 number here :-) **
 		//	return in
-		//}
+		// }
 		key := in[1 : len(in)-1]
-		value := queryParams.Get(key)
 		pathParams[key] = struct{}{}
-		return value
+		return queryParams.Get(key)
 	})
 	if !needQuery {
 		if v, ok := msg.(proto.Message); ok {
diff --git a/transport/http/codec.go b/transport/http/codec.go
index 5aef7995..39db4d21 100644
--- a/transport/http/codec.go
+++ b/transport/http/codec.go
@@ -7,12 +7,12 @@ import (
 	"net/http"
 	"net/url"
 
+	"github.com/gorilla/mux"
+
 	"github.com/go-kratos/kratos/v2/encoding"
 	"github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/internal/httputil"
 	"github.com/go-kratos/kratos/v2/transport/http/binding"
-
-	"github.com/gorilla/mux"
 )
 
 // SupportPackageIsVersion1 These constants should not be referenced from any other code.
diff --git a/transport/http/codec_go1.20.go b/transport/http/codec_go1.20.go
new file mode 100644
index 00000000..2df5ec92
--- /dev/null
+++ b/transport/http/codec_go1.20.go
@@ -0,0 +1,10 @@
+//go:build go1.20
+// +build go1.20
+
+package http
+
+import "net/http"
+
+// ResponseController is type net/http.ResponseController which was added in Go 1.20.
+
+type ResponseController = http.ResponseController
diff --git a/transport/http/resolver.go b/transport/http/resolver.go
index dbb2211f..bcbf8f3b 100644
--- a/transport/http/resolver.go
+++ b/transport/http/resolver.go
@@ -7,13 +7,13 @@ import (
 	"strings"
 	"time"
 
+	"github.com/google/uuid"
+
+	"github.com/go-kratos/aegis/subset"
 	"github.com/go-kratos/kratos/v2/internal/endpoint"
 	"github.com/go-kratos/kratos/v2/log"
 	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/go-kratos/kratos/v2/selector"
-
-	"github.com/go-kratos/aegis/subset"
-	"github.com/google/uuid"
 )
 
 // Target is resolver target
@@ -135,7 +135,7 @@ func (r *resolver) update(services []*registry.ServiceInstance) bool {
 	if r.subsetSize != 0 {
 		filtered = subset.Subset(r.selecterKey, filtered, r.subsetSize)
 	}
-	nodes := make([]selector.Node, 0)
+	nodes := make([]selector.Node, 0, len(filtered))
 	for _, ins := range filtered {
 		ept, _ := endpoint.ParseEndpoint(ins.Endpoints, endpoint.Scheme("http", !r.insecure))
 		nodes = append(nodes, selector.NewNode("http", ept, ins))
diff --git a/transport/http/server.go b/transport/http/server.go
index 7b27d326..8bece9af 100644
--- a/transport/http/server.go
+++ b/transport/http/server.go
@@ -9,15 +9,14 @@ import (
 	"net/url"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/internal/endpoint"
-	"github.com/go-kratos/kratos/v2/internal/matcher"
+	"github.com/gorilla/mux"
 
+	"github.com/go-kratos/kratos/v2/internal/endpoint"
 	"github.com/go-kratos/kratos/v2/internal/host"
+	"github.com/go-kratos/kratos/v2/internal/matcher"
 	"github.com/go-kratos/kratos/v2/log"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/transport"
-
-	"github.com/gorilla/mux"
 )
 
 var (


Test patch:
diff --git a/cmd/kratos/internal/proto/server/server_test.go b/cmd/kratos/internal/proto/server/server_test.go
index fa90f692..891f8bbb 100644
--- a/cmd/kratos/internal/proto/server/server_test.go
+++ b/cmd/kratos/internal/proto/server/server_test.go
@@ -60,3 +60,43 @@ func Test_serviceName(t *testing.T) {
 		})
 	}
 }
+
+func Test_parametersName(t *testing.T) {
+	type args struct {
+		name string
+	}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "parametersName on not nested",
+			args: args{
+				name: "MessageResponse",
+			},
+			want: "MessageResponse",
+		},
+		{
+			name: "parametersName on One layer of nesting",
+			args: args{
+				name: "Message.Response",
+			},
+			want: "Message_Response",
+		},
+		{
+			name: "parametersName on Two layer of nesting",
+			args: args{
+				name: "Message.Message2.Response",
+			},
+			want: "Message_Message2_Response",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := parametersName(tt.args.name); got != tt.want {
+				t.Errorf("parametersName() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/transport/http/binding/bind_test.go b/transport/http/binding/bind_test.go
index 6cd8b6d5..962292c4 100644
--- a/transport/http/binding/bind_test.go
+++ b/transport/http/binding/bind_test.go
@@ -1,6 +1,7 @@
 package binding
 
 import (
+	"errors"
 	"io"
 	"net/http"
 	"net/url"
@@ -8,47 +9,47 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/errors"
+	kratoserror "github.com/go-kratos/kratos/v2/errors"
 )
 
-func TestBindQuery(t *testing.T) {
-	type TestBind struct {
+type (
+	TestBind struct {
 		Name string `json:"name"`
 		URL  string `json:"url"`
 	}
-
-	type TestBind2 struct {
+	TestBind2 struct {
 		Age int `json:"age"`
 	}
-	p1 := TestBind{}
-	p2 := TestBind2{}
+)
+
+func TestBindQuery(t *testing.T) {
 	type args struct {
 		vars   url.Values
 		target interface{}
 	}
+
 	tests := []struct {
-		name    string
-		args    args
-		wantErr bool
-		want    interface{}
+		name string
+		args args
+		err  error
+		want interface{}
 	}{
 		{
 			name: "test",
 			args: args{
 				vars:   map[string][]string{"name": {"kratos"}, "url": {"https://go-kratos.dev/"}},
-				target: &p1,
+				target: &TestBind{},
 			},
-			wantErr: false,
-			want:    &TestBind{"kratos", "https://go-kratos.dev/"},
+			err:  nil,
+			want: &TestBind{"kratos", "https://go-kratos.dev/"},
 		},
 		{
 			name: "test1",
 			args: args{
 				vars:   map[string][]string{"age": {"kratos"}, "url": {"https://go-kratos.dev/"}},
-				target: &p2,
+				target: &TestBind2{},
 			},
-			wantErr: true,
-			want:    errors.BadRequest("CODEC", ""),
+			err: kratoserror.BadRequest("CODEC", "Field Namespace:age ERROR:Invalid Integer Value 'kratos' Type 'int' Namespace 'age'"),
 		},
 		{
 			name: "test2",
@@ -56,18 +57,17 @@ func TestBindQuery(t *testing.T) {
 				vars:   map[string][]string{"age": {"1"}, "url": {"https://go-kratos.dev/"}},
 				target: &TestBind2{},
 			},
-			wantErr: false,
-			want:    &TestBind2{Age: 1},
+			err:  nil,
+			want: &TestBind2{Age: 1},
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if err := BindQuery(tt.args.vars, tt.args.target); (err != nil) != tt.wantErr {
-				t.Errorf("BindQuery() error = %v, wantErr %v", err, tt.wantErr)
-			} else {
-				t.Log(err)
+			err := BindQuery(tt.args.vars, tt.args.target)
+			if !kratoserror.Is(err, tt.err) {
+				t.Fatalf("BindQuery() error = %v, err %v", err, tt.err)
 			}
-			if !tt.wantErr && !reflect.DeepEqual(tt.args.target, tt.want) {
+			if err == nil && !reflect.DeepEqual(tt.args.target, tt.want) {
 				t.Errorf("BindQuery() target = %v, want %v", tt.args.target, tt.want)
 			}
 		})
@@ -75,32 +75,25 @@ func TestBindQuery(t *testing.T) {
 }
 
 func TestBindForm(t *testing.T) {
-	type TestBind struct {
-		Name string `json:"name"`
-		URL  string `json:"url"`
-	}
-	type TestBind2 struct {
-		Age int `json:"age"`
-	}
-	p1 := TestBind{}
 	type args struct {
 		req    *http.Request
 		target interface{}
 	}
+
 	tests := []struct {
-		name    string
-		args    args
-		wantErr bool
-		want    interface{}
+		name string
+		args args
+		err  error
+		want *TestBind
 	}{
 		{
 			name: "error not nil",
 			args: args{
 				req:    &http.Request{Method: http.MethodPost},
-				target: &p1,
+				target: &TestBind{},
 			},
-			wantErr: true,
-			want:    nil,
+			err:  errors.New("missing form body"),
+			want: nil,
 		},
 		{
 			name: "error is nil",
@@ -110,10 +103,10 @@ func TestBindForm(t *testing.T) {
 					Header: http.Header{"Content-Type": {"application/x-www-form-urlencoded; param=value"}},
 					Body:   io.NopCloser(strings.NewReader("name=kratos&url=https://go-kratos.dev/")),
 				},
-				target: &p1,
+				target: &TestBind{},
 			},
-			wantErr: false,
-			want:    &TestBind{"kratos", "https://go-kratos.dev/"},
+			err:  nil,
+			want: &TestBind{"kratos", "https://go-kratos.dev/"},
 		},
 		{
 			name: "error BadRequest",
@@ -125,18 +118,17 @@ func TestBindForm(t *testing.T) {
 				},
 				target: &TestBind2{},
 			},
-			wantErr: true,
-			want:    nil,
+			err:  kratoserror.BadRequest("CODEC", "Field Namespace:age ERROR:Invalid Integer Value 'a' Type 'int' Namespace 'age'"),
+			want: nil,
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			err := BindForm(tt.args.req, tt.args.target)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("BindForm() error = %v, wantErr %v", err, tt.wantErr)
+			if !reflect.DeepEqual(err, tt.err) {
+				t.Fatalf("BindForm() error = %v, err %v", err, tt.err)
 			}
-			t.Log(err)
-			if !tt.wantErr && !reflect.DeepEqual(tt.args.target, tt.want) {
+			if err == nil && !reflect.DeepEqual(tt.args.target, tt.want) {
 				t.Errorf("BindForm() target = %v, want %v", tt.args.target, tt.want)
 			}
 		})
diff --git a/transport/http/client_test.go b/transport/http/client_test.go
index 063878af..25ae9a8e 100644
--- a/transport/http/client_test.go
+++ b/transport/http/client_test.go
@@ -227,7 +227,7 @@ func TestDefaultResponseDecoder(t *testing.T) {
 	resp1 := &http.Response{
 		Header:     make(http.Header),
 		StatusCode: 200,
-		Body:       io.NopCloser(bytes.NewBufferString("{\"a\":\"1\", \"b\": 2}")),
+		Body:       io.NopCloser(bytes.NewBufferString(`{"a":"1", "b": 2}`)),
 	}
 	v1 := &struct {
 		A string `json:"a"`
@@ -279,7 +279,7 @@ func TestDefaultErrorDecoder(t *testing.T) {
 	resp2 := &http.Response{
 		Header:     make(http.Header),
 		StatusCode: 500,
-		Body:       io.NopCloser(bytes.NewBufferString("{\"code\":54321, \"message\": \"hi\", \"reason\": \"FOO\"}")),
+		Body:       io.NopCloser(bytes.NewBufferString(`{"code":54321, "message": "hi", "reason": "FOO"}`)),
 	}
 	err := DefaultErrorDecoder(context.TODO(), resp2)
 	if err == nil {