背景
近期AWS Fargate在中国区正式落地,因Fargate使用Serverless架构,更加适合对性能要求不敏感的服务使用,Pyroscope是一款基于Golang开发的应用程序性能分析工具,Pyroscope的服务端为无状态服务且性能要求不敏感,使用EKS Fargate搭建Pyroscope,,Pyroscope的客户端使用DNS地址连接到服务端。将为单次性能测试和持续性能优化提供保障,并且每当应用服务上线或更新后,流量增加或者功能故障都会造成终端用户的体验变差,如何定位性能瓶颈便成为了重点,在EKS Fargate上搭建Pyroscope既能减少开发者的维护成本又能给开发者开箱即用的性能瓶颈快速定位到代码的平台,而且Pyroscope支持Python,Rust,NodeJS,Rube,Java,DotNet,Golang等多语言环境
使用场景
- 快速发现源代码中的存在的性能问题
- 根据指标监控发现高CPU利用率的问题
- 快速定位内存泄漏和修复辅助提供有效支撑
- 深入理解应用程序的调用耗时和依赖树
- 跟踪指标和时间轴以便于定位性能异常点
- 集成到CI定位每次变更的性能情况
介绍下Pyroscope
这是一款开源的实时性能监控平台,使用Agent/SDK – Server架构,让开发者可以轻松监控服务性能,因Pyroscope监控的级别足够深入。不管是最近5秒的数据还是长期存储的性能数据,都可以快速通过Grafana Plugin或者Pyroscope UI进行定位。且因为使用分块采样的能力。使得使用Pyrosocpe的Agent对应用程序的CPU占用较低。
Pyroscope Server 采用BadgerDB作为Key-value数据存储(未来将会支持S3兼容存储),具有高压缩比,低磁盘空间占用和低成本。支持多种语言和Docker,k8s,EC2等多种平台注入,Python,Rube,Java,DotNet 都是通过pyrosocope的命令启动相关Agent来执行监控,针对metric-export和eBPF有也有相关支持
Pyrosocpe UI 使用的方式和Grafana相似,可以使用Grafana Plugin也可以使用Pyroscope UI使用,名词使用:inuse_object,alloc_objects,inuse_space,alloc_space, 分别对应已分配或者尚未分配的对象在内存中的占用
Pyroscope UI
Pyroscope + Grafana Logs: 根据当前Logs volume找到存在性能问题的代码行,快速定位问题
Pyroscope + Tracing(Jaeger) : 根据Pyroscope_id在jaeger中找到对应的请求用于故障排除
性能告警
Pyrosocpe支持将应用服务性能指标导出到Prometheus,联动Prometheus全家桶进行服务耗时跟踪和性能的异常告警,只需要将Pyroscope配置到Prometheus配置文件中。使得Prometheus可以使用Kubernetes_sd 主动发现数据并采集上报
部署指南
git clone [github.com/Hoverhuang-er/eks-fargate-ppf](http://github.com/Hoverhuang-er/eks-fargate-ppf) && mv eks-fargate-ppf ppf
- 使用 Terraform 创建 AWS EKS Cluster 和 Fargate profile
cd ppf/eks && terraform init && terraform apply -auto-approve
---
apiVersion: v1
kind: Namespace
metadata:
name: fg1
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
namespace: fg1
name: pyroscope-server
spec:
volumeClaimTemplates:
- metadata:
name: pyroscope-server-storage
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "gp2"
resources:
requests:
storage: 8Gi
minReadySeconds: 10
selector:
matchLabels:
app.kubernetes.io/name: pyroscope-server
replicas: 1
template:
metadata:
labels:
app.kubernetes.io/name: pyroscope-server
spec:
containers:
- image: dockerhub.io/pyroscope/pyroscope:latest
imagePullPolicy: Always
name: pyroscope-server
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: fg1
name: pyroscope-server-services
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: NodePort
selector:
app.kubernetes.io/name: pyroscope-server
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: fg1
name: pyroscope-server-ingress
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /*
pathType: Prefix
backend:
service:
name: pyroscope-server
port:
number: 80
- 使用 Skooner或者 [Potainer.io](http://Potainer.io) 对EKS 集群进行简单管理
- kubectl apply -f ppf/dashboard.yaml
如何使用Pyroscope进行性能优化
Pyroscope具有代码侵入性,如需进一步使用,请谨慎考虑
样例代码:Ruby
require "pyroscope"
Pyroscope.configure do |config|
config.app_name = "test.ruby.app"
config.server_address = ENV["PYROSCOPE_SERVER_ADDRESS"]
config.tags = {
:region => "ap-southeast-1",
:hostname => ENV["HOSTNAME"]
}
end
def work(n)
i = 0
while i < n
i += 1
end
end
def fast_function
Pyroscope.tag_wrapper({ "function" => "fast" }) do
work(20000)
end
end
def slow_function
Pyroscope.tag({ "function" => "slow" })
work(80000)
Pyroscope.remove_tags("function")
end
while true
fast_function
slow_function
end
用于部署的Dockerfile:
FROM ruby:3.0.1
WORKDIR /usr/src/app
RUN adduser --disabled-password --gecos --quiet pyroscope
USER pyroscope
COPY --from=pyroscope/pyroscope:latest /usr/bin/pyroscope /usr/bin/pyroscope
COPY main.rb ./main.rb
COPY Gemfile ./Gemfile
COPY Gemfile.lock ./Gemfile.lock
ENV PYROSCOPE_APPLICATION_NAME=simple.ruby.app
ENV PYROSCOPE_SERVER_ADDRESS=http://172.31.0.233:4040/
ENV PYROSCOPE_LOG_LEVEL=debug
RUN bundle install
CMD ["ruby", "main.rb"]
运行App即可发现性能问题
综述
使用Pyroscope有助于开发人员持续提高应用程序的性能。减少耗时爆点的存在和影响,并可以将数据输出到Grafana,协助开发人员持续优化服务并有效降低成本,使用AWS EKS Fargate 搭建Pyroscope在帮助开发人员和维护人员进行系统服务性能架构优化的同时,基于Serveless contaienr减少维护成本。
本篇作者