RacketMQ 5.X 的发布,向云原生迈出了一大步。从官方的文档中,我们可以看到其中最大的一块变化是新增了 Proxy 模块,新旧版本架构对比如下:
RocketMQ 4.X 架构
RocketMQ 5.X 架构
在 RocketMQ4.X 的时候,深入使用过 RocketMQ 的人很多都可能遇到一个问题,RocketMQ 在复杂网络下是有缺陷的,比如说网上就有很多人问 RocketMQ 如何同时对内网和外网提供服务。得到的答案可能是让你修改brokerIP1、brokerIP2,brokerIP1 指向公网IP,brokerIP2 指向内网IP。但是这样并不能解决问题,因为 NameServer 始终会向客户端返回 brokerIP1 的地址,并不是真正解决了内外网的问题。
使用GitLab的时候,开发者是可以随意设置其用户名和邮箱的。
git config --global user.name "abc"
git config --global user.email "123"
像我这样设置,代码依然可以正常提交,在gitlab上查看的时候显示的用户名是“abc”。
Git本身精神就是协作,是自由、平等,而非集权式的代码库。这样设计也没毛病,但是在公司的代码管理中,这样就很不好,尤其是在开发 Leader review 代码的时候,如果没有正确配置用户名可能都不知道这代码是谁写的。
众所周知的原因,在国内访问Jenkins的插件站点不是很稳定,经常访问很慢或者超时。
如果你网上搜索Jenkins更换国内源
等关键字,大多数文章都会告诉你做以下三个步骤:
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
/var/jenkins_home/updates/default.json
文件内容中https://updates.jenkins.io/download
替换为国内源,如https://mirrors.tuna.tsinghua.edu.cn/jenkins
第一步有一个坑:https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json下载的是始终是最新的插件,和旧版本的Jenkins是不兼容的,要替换为https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/dynamic-stable-VERSION/update-center.json
才能装到匹配的插件版本,其中VERSION
是当前Jenkins的版本。如果不是LTS版本,则dynamic-stable-VERSION
要换成dynamic-VERSION
。
第二步修改了之后,过一段时间你想再装插件你会发现/var/jenkins_home/updates/default.json
这个文件又被恢复成官方的了。此举并不是一劳永逸的,因为Jenkins会定时更新这个文件。
那么有没有更好的办法呢?答案是有的,下面就教大家如何一劳永逸地将Jenkins插件站点换为你想要的任何镜像站点。
方法示意图:
需要解决一个问题,Jenkins源站点是https协议的,Jenkins会校验SSL证书的有效性,因此我这里将使用nginx的sub_filter模块将update-center.json
返回的内容修改为http协议的。
正在运行的gitlab集群突然抽风,具体故障现象如下。
环境信息:gitlab部署在k8s集群内,采用官方helm包部署,gitlab版本为14.10.x。
故障现象:项目相关的操作有几率报错
An error occurred while fetching folder content.
查看Gitaly服务的日志,发现是Praefect服务调用Gitaly的健康检查接口报错,错误关键信息为 PermissionDenied。
{"correlation_id":"01G7BX3DR59H35EYHPMKHNVBC0","error":"rpc error: code = PermissionDenied desc = permission denied","grpc.code":"PermissionDenied","grpc.meta.auth_version":"v2","grpc.meta.deadline_type":"unknown","grpc.meta.method_type"
:"unary","grpc.method":"Check","grpc.request.deadline":"2022-07-07T08:39:54.207","grpc.request.fullMethod":"/grpc.health.v1.Health/Check","grpc.request.payload_bytes":0,"grpc.response.payload_bytes":0,"grpc.service":"grpc.health.v1.Healt
h","grpc.start_time":"2022-07-07T08:39:53.208","grpc.time_ms":0.285,"level":"warning","msg":"finished unary call with code PermissionDenied","peer.address":"10.42.1.134:51266","pid":12,"span.kind":"server","system":"grpc","time":"2022-07-07T08:39:53.208Z"}
{"correlation_id":"01G7BX3EQJZJFT996MD2KF2HXW","error":"rpc error: code = PermissionDenied desc = permission denied","grpc.code":"PermissionDenied","grpc.meta.auth_version":"v2","grpc.meta.deadline_type":"unknown","grpc.meta.method_type":"unary","grpc.method":"Check","grpc.request.deadline":"2022-07-07T08:39:55.212","grpc.request.fullMethod":"/grpc.health.v1.Health/Check","grpc.request.payload_bytes":0,"grpc.response.payload_bytes":0,"grpc.service":"grpc.health.v1.Health","grpc.start_time":"2022-07-07T08:39:54.213","grpc.time_ms":0.201,"level":"warning","msg":"finished unary call with code PermissionDenied","peer.address":"10.42.1.134:51266","pid":12,"span.kind":"server","system":"grpc","time":"2022-07-07T08:39:54.213Z"}
*** /var/log/gitaly/gitaly_ruby_json.log ***
{"type":"gitaly-ruby","grpc.start_time":"2022-07-07T08:39:53Z","grpc.time_ms":0.286,"grpc.code":"OK","grpc.method":"Check","grpc.service":"grpc.health.v1.Health","pid":35,"correlation_id":"c486ca8b2bbc3eb6736d533c38cf6017","time":"2022-07-07T08:39:53.642Z"}
{"type":"gitaly-ruby","grpc.start_time":"2022-07-07T08:39:53Z","grpc.time_ms":17.012,"grpc.code":"OK","grpc.method":"Check","grpc.service":"grpc.health.v1.Health","pid":36,"correlation_id":"71bff8c80424d633989f5daeb29111c3","time":"2022-07-07T08:39:53.658Z"}
*** /var/log/gitaly/gitaly.log ***
{"correlation_id":"01G7BX3FPZ8BTMCA0RY5754JGJ","error":"rpc error: code = PermissionDenied desc = permission denied","grpc.code":"PermissionDenied","grpc.meta.auth_version":"v2","grpc.meta.deadline_type":"unknown","grpc.meta.method_type":"unary","grpc.method":"Check","grpc.request.deadline":"2022-07-07T08:39:56.217","grpc.request.fullMethod":"/grpc.health.v1.Health/Check","grpc.request.payload_bytes":0,"grpc.response.payload_bytes":0,"grpc.service":"grpc.health.v1.Health","grpc.start_time":"2022-07-07T08:39:55.218","grpc.time_ms":0.135,"level":"warning","msg":"finished unary call with code PermissionDenied","peer.address":"10.42.1.134:51266","pid":12,"span.kind":"server","system":"grpc","time":"2022-07-07T08:39:55.218Z"}
{"correlation_id":"01G7BX3GPCRD1RPMN7F3WN6X14","error":"rpc error: code = PermissionDenied desc = permission denied","grpc.code":"PermissionDenied","grpc.meta.auth_version":"v2","grpc.meta.deadline_type":"unknown","grpc.meta.method_type":"unary","grpc.method":"Check","grpc.request.deadline":"2022-07-07T08:39:57.222","grpc.request.fullMethod":"/grpc.health.v1.Health/Check","grpc.request.payload_bytes":0,"grpc.response.payload_bytes":0,"grpc.service":"grpc.health.v1.Health","grpc.start_time":"2022-07-07T08:39:56.223","grpc.time_ms":0.189,"level":"warning","msg":"finished unary call with code PermissionDenied","peer.address":"10.42.1.134:51266","pid":12,"span.kind":"server","system":"grpc","time":"2022-07-07T08:39:56.223Z"}
解决:服务器之间做好时间同步就好了
项目中使用到了RabbitMQ,使用了大量的一次性队列,然而没有设置自动过期、自动删除等特性。长期运行导致了大量的队列产生,非常影响性能及问题排查效率。这里收集了一些可以批量删除队列的方法,供参考。
优点:操作简单,可针对有规律的队列进行策略设置
缺点:想不到有什么缺点
# 设置规则
rabbitmqctl set_policy delete_gen "amq.gen-.*" '{"expires":1}' --apply-to queues
# 取消规则
rabbitmqctl clear_policy delete_gen
# 如果要作用于所有队列
rabbitmqctl set_policy delete_all ".*" '{"expires":1}' --apply-to queues
优点:简单,删除全部队列
缺点:粗暴
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
优点:删除一个vhost的所有队列,包括Exchange
缺点:仅适用需要删除一个vhost的场景
curl -i -XDELETE http://USERNAME:[email protected]:15672/api/vhosts/VHOST_NAME
# 例子
curl -i -XDELETE http://admin:[email protected]:15672/api/vhosts/%2F
优点:HTTP API灵活
缺点:一次删一个
curl -i -XDELETE http://USERNAME:[email protected]:PORT/api/queues/VHOST/QUEUE_NAME
# 例子:
curl -i -XDELETE http://admin:[email protected]:15672/api/queues/%2F/test_queue
优点:使用方便
缺点:底层也是使用HTTP API实现的
rabbitmqadmin --host=HOST --port=15672 --ssl --vhost=VHOST --username=USERNAME --password=PASSWORD delete queue name=QUEUE_NAME