添加我们自己的module,找到这个文件 \caddy\modules\caddyhttp\standard\imports.go
package standardimport (// standard Caddy HTTP app modules_ "github.com/caddyserver/caddy/v2/modules/caddyhttp"_ "github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyauth"//other..._ "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy"//other..//添加我们的package_ "github.com/caddyserver/caddy/v2/modules/caddyhttp/nacosgateway" )
先看看我们的配置,Caddyfile文件部分节点
:2015 {bind localhost 192.168.1.133root * D:\myenv\webvufile_server {index index.html index.htm}handle /gate/* {uri strip_prefix /gate reverse_proxy {dynamic nacos { server_addr 192.168.1.109server_port 8848name_space myenvgateway_addr 192.168.1.133gateway_port 2015gateway_service caddy}}} }
以下是部分关键代码。程序会在启动时向nacos注册caddy服务。/gate/{service}/htmlurl的请求来时,会向nacos获取{service}的实际地址,将/htmlurl转到该地址上。
package nacosgatewayimport ("fmt""net/http""strconv""strings""sync""github.com/caddyserver/caddy/v2""github.com/caddyserver/caddy/v2/caddyconfig/caddyfile""github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy""github.com/nacos-group/nacos-sdk-go/v2/clients""github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client""github.com/nacos-group/nacos-sdk-go/v2/common/constant""github.com/nacos-group/nacos-sdk-go/v2/model""github.com/nacos-group/nacos-sdk-go/v2/vo" )func init() {caddy.RegisterModule(NacosUpstreamSource{}) }// NacosUpstreamSource 实现了 UpstreamSource 接口 type NacosUpstreamSource struct {ServerAddr string `json:"server_addr,omitempty"`ServerPort uint64 `json:"server_port,omitempty"` NameSpace string `json:"namespace,omitempty"`GatewayAddr string `json:"gateway_addr,omitempty"`GatewayPort uint64 `json:"gateway_port,omitempty"`GatewayService string `json:"gateway_service,omitempty"`client naming_client.INamingClientupstreamCache map[string][]*reverseproxy.Upstream // 新增缓存字段cacheMutex sync.RWMutex // 用于保护缓存的读写锁 }// 初始化 NacosUpstreamSource 时初始化缓存 func NewNacosUpstreamSource() *NacosUpstreamSource {return &NacosUpstreamSource{// 其他字段初始化...upstreamCache: make(map[string][]*reverseproxy.Upstream),} }// Provision 初始化 Nacos 客户端 func (n *NacosUpstreamSource) Provision(ctx caddy.Context) error {serverConfigs := []constant.ServerConfig{{IpAddr: n.ServerAddr,Port: n.ServerPort,},}clientConfig := constant.ClientConfig{NamespaceId: n.NameSpace,TimeoutMs: 5000,NotLoadCacheAtStart: true,LogDir: "/tmp/nacos/log",CacheDir: "/tmp/nacos/cache",}var err errorn.client, err = clients.NewNamingClient(vo.NacosClientParam{ClientConfig: &clientConfig,ServerConfigs: serverConfigs,},)if err != nil {return err}// 注册服务实例success, err0 := n.client.RegisterInstance(vo.RegisterInstanceParam{Ip: n.GatewayAddr,Port: n.GatewayPort,ServiceName: n.GatewayService})if err0 != nil {panic(err0)}if !success {return fmt.Errorf("Service registration failed")}return nil }// GetUpstreams 从 Nacos 获取服务列表 func (n *NacosUpstreamSource) GetUpstreams(r *http.Request) ([]*reverseproxy.Upstream, error) {// 提取 URL 中的服务名serviceName, newPath := extractServiceName(r.URL.Path)// 从 URL 中去掉 /{service} 部分r.URL.Path = newPathif serviceName == "" {// 如果没有提取到,使用默认服务名return nil, fmt.Errorf("No service name found in URL")}// 先从缓存中查找n.cacheMutex.RLock()upstreams, exists := n.upstreamCache[serviceName]n.cacheMutex.RUnlock()if exists {return upstreams, nil}serviceInfo, err := n.client.GetService(vo.GetServiceParam{ServiceName: serviceName,})if err != nil {return nil, err}if len(serviceInfo.Hosts) == 0 {return nil, fmt.Errorf("No instances found for service %s", serviceName)}// 构建 Upstreamupstreams = make([]*reverseproxy.Upstream, 0, len(serviceInfo.Hosts))for _, instance := range serviceInfo.Hosts {upstream := &reverseproxy.Upstream{Dial: fmt.Sprintf("%s:%d", instance.Ip, instance.Port),}upstreams = append(upstreams, upstream)}// 将结果存入缓存n.cacheMutex.Lock()n.upstreamCache[serviceName] = upstreamsn.cacheMutex.Unlock()return upstreams, nil }// CaddyModule 返回模块信息 func (NacosUpstreamSource) CaddyModule() caddy.ModuleInfo {return caddy.ModuleInfo{ID: "http.reverse_proxy.upstreams.nacos",New: func() caddy.Module { return NewNacosUpstreamSource() },} }func (n *NacosUpstreamSource) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {d.Next() // 跳过指令名: nacosfor d.NextBlock(0) {switch d.Val() {case "server_addr":if !d.NextArg() {return d.ArgErr()}n.ServerAddr = d.Val()//其他属性case "gateway_service":if !d.NextArg() {return d.ArgErr()}n.GatewayService = d.Val()default:return d.Errf("unrecognized subdirective %s", d.Val())}}return nil }var _ caddy.Provisioner = (*NacosUpstreamSource)(nil) var _ reverseproxy.UpstreamSource = (*NacosUpstreamSource)(nil)
后面学习一下seaweedfs的源代码。