社区的一些微服务框架:
//import "github.com/emicklei/go-restful/v3"
r := restful.DefaultContainer
// 设置默认ContentType
restful.DefaultResponseContentType(restful.MIME_JSON)
restful.DefaultRequestContentType(restful.MIME_JSON)
// CORS中间件
cors := restful.CrossOriginResourceSharing{
AllowedHeaders: []string{"*"},
AllowedDomains: []string{"*"},
AllowedMethods: []string{"HEAD", "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE"},
CookiesAllowed: false,
Container: r,
}
// 使用Filter加载 GoRestful中间件(等同于Gin Use)
r.Filter(cors.Filter)
// LoadHttpApp 装载所有的http app
func LoadGoRestfulApi(pathPrefix string, root *restful.Container) {
objects := store.Namespace(ApiNamespace)
for _, obj := range objects.Items {
api, ok := obj.(GoRestfulApiObject)
if !ok {
continue
}
// 为模块创建一个WebService
pathPrefix = strings.TrimSuffix(pathPrefix, "/")
ws := new(restful.WebService)
ws.
Path(fmt.Sprintf("%s/%s/%s", pathPrefix, api.Version(), api.Name())).
Consumes(restful.MIME_JSON, form.MIME_POST_FORM, form.MIME_MULTIPART_FORM, yaml.MIME_YAML, yamlk8s.MIME_YAML).
Produces(restful.MIME_JSON, yaml.MIME_YAML, yamlk8s.MIME_YAML)
//把模块里面的路由 通通注册到这个WebService
api.Registry(ws)
// webservice 添加到container
root.Add(ws)
}
}
从Protobuf的角度看,gRPC只不过是一个针对service接口生成代码的生成器。因此我们需要提前安装grpc的代码生成插件
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest 生成tag插件:go get https://github.com/favadi/protoc-go-inject-tag
项目的根路径: devcloud-mini(作为一个微服务工程)
需要进入mcenter项目内进行代码生成
$ protoc -I=. --go_out=.. --go-grpc_out=.. --go_opt=module="gitee.com/wshadm/go11/devcloud-mini" --go-grpc_opt=module="gitee.com/wshadm/go11/devcloud-mini" mcenter/apps/token/*/*.proto
xxx.pb.go生成在什么位置取决于:
1、xxx.proto中的option go_package="gitee.com/wshadm/go11/devcloud-mini/mcenter/apps/token";
2、--go_out和--go-grpc_out的位置
示例:在/d/gocode/dev-golang/devcloud/devcloud-mini目录中执行protocl命令
$ protoc -I=. --go_out=. --go-grpc_out=. --go_opt=module="gitee.com/wshadm/go11/devcloud-mini" --go-grpc_opt=module="gitee.com/wshadm/go11/devcloud-mini" cmdb/apps/*/pb/*.proto
pb.go文件中的go_package"gitee.com/wshadm/go11/devcloud-mini/mcenter/apps/token";
由于--go_out=.. --go-grpc_out=..都是用的"..",那么输出路径会往上一层输出,导致在上一层新建了目录:
mcenter/apps/token/xxx.pb.go
提问chatgpt:是不是可以简单理解为.proto文件中的go_package路径在哪,最终pb.go就会生成到哪里
是的,你的理解基本正确。在 Protocol Buffers 的 .proto 文件中,通过 go_package 选项指定 Go 代码生成的路径。这个路径包括了包名和生成的 .pb.go 文件的相对位置。
例如,如果你的 .proto 文件中有如下声明:
option go_package = "gitee.com/wshadm/go11/devcloud-mini/mcenter/apps/token";
这将指示 Protocol Buffers 编译器生成的 Go 代码的包名为 token,而且生成的 .pb.go 文件将被放置在 gitee.com/wshadm/go11/devcloud-mini/mcenter/apps/token 目录下。
这样的设计有助于将生成的代码与其他 Go 项目或模块进行隔离,同时也使得生成的代码的导入路径具有意义。在使用 protoc 编译命令时,通过 --go_out 选项指定的输出目录与 go_package 中指定的路径相关联。
在过程中经常遇到rpc.proto文件中不能正常import(例如meta.proto),最后修改为与学习项目结构一致D:/go11/devcloud-mini恢复了,要多练
再执行: protoc-go-inject-tag -input="cmdb/apps//.pb.go"
go install google.golang.org/protobuf/cmdb/protoc-gen-go@latest
go install google.golang.org/grpc/cmdb/protoc-gen-go-grpc@latest
go install github.com/favadi/protoc-go-inject-tag@latest
// API Doc
h.r.Add(apidoc.APIDocs(h.apiDocPath, swagger.Docs))
logger.L().Debug().Msgf("Swagger API Doc访问地址: http://%s%s", conf.C().Http.Address(), h.apiDocPath)
配置对象 1、单独的对象 mysql对象 http对象 Grpc对象 。。 2、对象的集合,封装到一个统一的配置对象当中 type Config struct { m *mysql h *http g *Grpc } 3、配置的初始化给一些默认配置,func NewConfig() *Config {} 读取配置 动态?还是? 不给路径就读默认,给了就赋值 修改配置时要有sycn.Mutex, 可以封装一个函数暴露全局供调用var config *Config , func C() *Config,其它不暴露。
日志库:定义日志的级别
protocol协议配置: [http配置]:创建httpserver对象,是用gin的,还是go-Restful的?协议配置, 当中定义httpserver的属性和配置(例如 是否需要跨域),读取config中http相关配置,如ip,port,超时时间等等 配置[start]和[stop]部分,当中可以加[swagger文档]的配置
Grpc配置:创建grpc.server对象和start、stop 同样也要读取config中的配置信息,ip port等
权限最小化原则,流程 在 Go 语言中,接口权限最小化原则通常指的是在定义接口时,只包含必要的方法,以减少接口的复杂性和依赖性。这个原则与软件设计中的最小权限原则相似,目的是限制接口的暴露,使其只暴露出必要的行为,而不是暴露过多的细节。 内部服务实现interface接口就好,grpc或rpc则只暴露client端需要的接口方法就好,不必暴露过多
因此,确保内部服务实现的接口仅用于服务内部调用,并且只暴露给客户端需要的接口方法,是一个很好的设计原则,有助于提高系统的可维护性和安全性。
使用 .proto 文件定义了要暴露给客户端的接口以及数据对象格式。这个文件定义了消息的结构和服务接口的方法。然后,使用 Protocol Buffers 的编译器(如 protoc)根据这个 .proto 文件生成相应语言的代码,例如 Go 语言的 .pb.go 文件。
生成的 .pb.go 文件中包含了客户端和服务端都可以使用的代码:
服务端代码:.pb.go 文件中包含了服务端需要实现的接口,这些接口定义了客户端可以调用的方法。服务端需要实现这些接口来提供具体的功能。
客户端代码:同样的 .pb.go 文件中也包含了客户端需要使用的代码,这些代码提供了对服务端定义的方法的调用接口。客户端可以使用这些方法来与服务端通信。
因此,.pb.go 文件是根据 .proto 文件生成的,其中包含了客户端和服务端所需的代码。这种方式使得定义接口和消息格式更加方便,并且通过自动生成代码,简化了客户端和服务端之间进行 RPC 或 gRPC 通信的过程。
rpc_grpc.pb.go) 文件通常包含 gRPC 协议相关的代码,其中包括根据 .proto 文件生成的 gRPC 服务接口的客户端和服务器端的代码,以及消息格式和序列化相关的代码。
rpc.pb.go 可能包含一些额外的业务逻辑代码,用于实现 .proto 文件中定义的 gRPC 服务接口中的方法。它也是根据 .proto 文件生成的,但可能包含了一些额外的业务逻辑,这取决于您是否在 .proto 文件中定义了自定义的方法或业务逻辑
impl控制器 init初始化时,用ioc注册业务的实现 显式的约束对象实现接口,以及实现Grpcserver和Ioc的接口,编写ioc的相关方法 注册Grpcserver和impl业务实现,给客户端用的, 这个注册过程意味着将 impl 中定义的远程过程调用(RPC)服务方法暴露给客户端, 使得客户端能够通过 gRPC 连接调用这些方法。 业务实现,token的颁发和删除
api当中都是在使用Grpc、rpc协议时使用的。做了权限最小化。只暴露必要的 api-http 当中同样有IOC注册,来获取业务的实现方法
api-token 通过绑定Handler和业务方法,来使用。当前使用的是GoRestful,需要符合框架签名。以及信息的自动脱敏。
cmd cobra命令行代码,启动http服务和Grpc服务,以及初始化业务部分的init方法
消息队列:kafka topic主题: 同一类消息在同一个topic中 partion分区: 一个topic可以分多个partion每个partition在存储层面是append log文件。任何发布到此partition的消息都会被直接追加到log文件的尾部
消费者组: img.png消费者组订阅一个主题,意味着主题下的所有分区都会被组中的消费者消费到, 并且主题下的每个分区只从属于组中的一个消费者,不可能出现组中的两个消费者负责同一个分区。 消费者从partition中消费数据,consumer有group的概念,每个group可以消费完整的一份topic中的数据。
如果分区数大于或者等于组中的消费者实例数,那么一个消费者会负责多个分区;如果消费者实例的数量大于分区数,有一些消费者是多余的,一直接不到消息而处于空闲状态。 即: 若consumer数量大于partition数量,会造成限制的consumer,产生浪费。 若consumer数量小于partition数量,会导致均衡失效,其中的某个或某些consumer会消费更多的任务。 消费分区是有策略的:https://cloud.tencent.com/developer/article/1953243
生产者: offset偏移量:每条消息在文件中的位置称为offset(偏移量),offset为一个long型数字,它是唯一标记一条消息。它唯一的标记一条消息。 kafka并没有提供其他额外的索引机制来存储offset,因为在kafka中几乎不允许对消息进行“随机读写”
v1:
#!/bin/bash
stop_application() {
#process_name=ps -ef | grep start
app_pid=$(lsof -ti tcp:8080)
if [ -n "$app_pid" ]; then
#kill -15 $app_pid
lsof -ti tcp:8080 | xargs kill -15
wait $app_pid
}
handle_sigterm() { stop_application exit 0 }
trap 'handle_sigterm' SIGTERM
#!/bin/bash
stop_application() {
process_name=ps -ef | grep start
app_pid=$(ps -ef | grep $process_name | grep -v grep | awk '{print $2}')
if [ -n "$app_pid" ]; then
kill -15 $app_pid
wait $app_pid
else
echo "Application process not found."
fi
}
handle_sigterm() { stop_application exit 0 }
trap 'handle_sigterm' SIGTERM
wait $app_pid
16:35
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。