1、背景
传统的arthas服务部署,要求每个服务实例都提供单独的监控,这样在云上环境维护跟使用成本都明显拉高。因此,我们可以利用arthas tunnel来解决这个问题。
2、基础介绍
官方原话:通过 Arthas Tunnel Server/Client 来远程管理/连接多个 Agent。官网地址
也就是通过一个tunnel服务,连接其它所有的arthas单点服务,通过AgentId区别,统一维护的入口跟方式。
3、制作镜像
由于dockerhub网站的访问不够友好,导致线上服务器无法拉取tunnel镜像,而arthas官网也并未提供tunnel镜像。因此我们打算自己制作一个tunnel镜像,原理也就是利用tunnel jar包进行部署,开放固定端口即可。
3.1、下载arthas tunnel jar包
https://github.com/alibaba/arthas/releases
3.2、编写dockerfile
FROM 192.168.0.1:7000/abc/adc_jdk8:v1.0
LABEL MAINTAINER=json
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
RUN mkdir -p /home/adc-arthas/config
# 下载地址改成你的服务地址,或者在文件在本地的话用COPY也行
ADD http://192.168.0.1:8080/vue/arthas-tunnel-server-4.0.4-fatjar.jar /home/adc-arthas/
# 同上
ADD http://192.168.0.1:8080/vue/run.sh /home/adc-arthas/
RUN chmod +x /home/abc-arthas/run.sh
# ldc-acc服务-结束
CMD ["/home/adc-arthas/run.sh"]
3.3、制作启动脚本run.sh
这里单独制作启动命令的目的,主要是方便混合命令的使用。
#!/bin/bash
java -Dfile.encoding=utf8 -Xms2048m -Xmx4096m -jar /home/adc-arthas/arthas-tunnel-server-4.0.4-fatjar.jar
#sleep infinity
3.4、镜像上传到内网docker仓库,harbor
# 先编译出镜像
docker build -t adc_arthas_tunnel:v1.0 .
# 新增私服命名标签
docker tag adc_arthas_tunnel:v1.0 192.168.0.1:7000/adc/adc_arthas_tunnel:v1.0
# 上传到私服仓库
docker push 192.168.0.1:7000/adc/adc_arthas_tunnel:v1.0
4、云上搭建
4.1、制作工作负载
创建并应用:arthas-tunnel-deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: abc-arthas-tunnel
namespace: abc-live-project
labels:
abc-arthas: abc-arthas-tunnel
annotations:
deployment.kubernetes.io/revision: '1'
kubesphere.io/alias-name: arthas监控服务
kubesphere.io/creator: igor
kubesphere.io/description: arthas监控服务
spec:
replicas: 1
selector:
matchLabels:
abc-arthas: arthas-tunnel
template:
metadata:
labels:
abc-arthas: arthas-tunnel
annotations:
kubesphere.io/creator: igor
spec:
containers:
- name: abc-container-arthas-tunnel
image: '192.168.0.1:7000/abc/abc_arthas_tunnel:v1.0'
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: tcp
containerPort: 7777
protocol: TCP
resources:
limits:
cpu: '2'
memory: 4Gi
requests:
cpu: '2'
memory: 2000Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: IfNotPresent
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
securityContext: {}
imagePullSecrets:
- name: harbor-private-secret-xxxx
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 100%
maxSurge: 100%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600
4.2、搭建集群内访问服务端口
创建并应用:arthas-tunnel-cluster.yaml
kind: Service
apiVersion: v1
metadata:
name: abc-arthas-tunnel-cluster
namespace: abc-live-project
labels:
app: abc-arthas-tunnel-cluster
annotations:
kubesphere.io/creator: igor
spec:
ports:
- name: http-8080
protocol: TCP
port: 18080
targetPort: 8080
- name: tcp-7777
protocol: TCP
port: 17777
targetPort: 7777
selector:
abc-arthas: arthas-tunnel
# 分配的集群内IP,改成你的
clusterIP: 10.223.16.1
clusterIPs:
- 10.223.16.1 # 同上
type: ClusterIP
sessionAffinity: None
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
internalTrafficPolicy: Cluster
4.3、搭建机器外访问服务端口
创建并应用:arthas-tunnel-node.yaml
kind: Service
apiVersion: v1
metadata:
name: abc-arthas-tunnel-node
namespace: abc-live-project
labels:
app: abc-arthas-tunnel-node
annotations:
kubesphere.io/creator: igor
spec:
ports:
- name: http-7777
protocol: TCP
port: 17777
targetPort: 7777
nodePort: 30758
- name: http-8080
protocol: TCP
port: 18080
targetPort: 8080
nodePort: 30592
selector:
abc-arthas: arthas-tunnel
# 分配的集群内IP,改成你的
clusterIP: 10.223.14.75
clusterIPs:
- 10.223.14.75 # 同上
type: NodePort
sessionAffinity: None
externalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
internalTrafficPolicy: Cluster
4.4、测试arthas tunnel server状态
http://10.10.1.111:30592/
IP即云上任何节点,30592即8080的外部访问端口,注意修改为你的。
5、java服务接入
5.1、新增配置项
考虑到 pod 会以 deploy 等方式部署到 kubernetes 集群中,那么此时 多个pod的agent-id 是会冲突的。
解决方案:
对每台node都声明一个环境变量,比如node_name: 机器名。即: agent-id: ${node_name}-abc-xxx-server。
K8s Pod示例(deployment.yaml)
env:
- name: node_name # 环境变量名(注意大小写)
valueFrom:
fieldRef:
fieldPath: spec.nodeName # 或使用其他唯一标识(如metadata.name)
application.yml 示例
# 最外层,无嵌套
arthas:
# 不能重复
agent-id: abc-xxx-server
# 改成4.2的集群内IP
tunnel-server: ws://10.223.16.1:17777/ws
# 改成你的
app-name: ${node_name}-abc-xxx-server-app
# 不启用
http-port: 0
# 不启用
telnet-port: 0
5.2、pom引入jar(推荐)
<!-- arthas监控 -->
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-spring-boot-starter</artifactId>
<version>3.5.4</version>
</dependency>
5.3、启动命令带上agent(不推荐,不好维护)
java -javaagent:/tmp/test/arthas-agent.jar -jar your-server.jar
6、服务监控验证

7、实战案例
对线上的类代码进行热更,比如注释一行代码,或者修改变量的传参等。
# 1、查看类的装载信息,得到类加载器ID
sc -d com.xxx.common.utils.HttpUtils
# 2、反编译该类到文件
jad --source-only com.xxx.common.utils.HttpUtils > /home/HttpUtils.java
# 3、修改代码
vim /home/HttpUtils.java
# 4、编译修改后的代码
mc -c <1edf1c96-类加载器ID> /home/HttpUtils.java -d /tmp
# 5、热更新 (redefine容易无效,官网推荐retransform)
retransform /tmp/com/xxx/common/utils/HttpUtils.class
over.
2739

被折叠的 条评论
为什么被折叠?



