Python 应用可观测重磅上线:解决 LLM 应用落地的“最后一公里”问题-应用示例

为方便大家理解和感受 Python 探针的功能,本文构建了一个 LLM 应用的示例:

某公司升级了其产品,新增了智能问答功能。其基本架构图如下:

基本业务流程为用户向 server 端发起一个问答请求,server 去调用 chatbot 获取回复结果,chatbot 收到请求后进行 RAG 后回复。

为观测此 LLM 应用,该公司接入了阿里云 Python 探针。下文将介绍如何接入阿里云 Python 探针。

Python 应用接入应用监控

以下为在 ACK 环境下 Python 探针的接入方式,其他接入方式见:https://help.aliyun.com/zh/arms/application-monitoring/user-guide/start-monitoring-python-applications/

前提条件

  • 创建 Kubernetes 集群。您可按需选择创建 ACK 专有集群、创建 ACK 托管集群或创建 ACK Serverless 集群。
  • 创建命名空间,具体操作,请参见管理命名空间与配额。本文示例中的命名空间名称为 arms-demo。
  • 检查您的 Python 版本和框架版本。具体要求,请参见 Python 探针兼容性要求。

步骤一:安装 ARMS 应用监控组件

  1. 登录容器服务管理控制台 [ 1]

  2. 在左侧导航栏单击集群,然后在集群列表页面单击目标集群名称。

  3. 在左侧导航栏选择运维管理 > 组件管理,然后在右上角通过关键字搜索 ack-onepilot。 (重要:请确保 ack-onepilot 的版本在 3.2.4 及以上。)

  4. 在 ack-onepilot 卡片上单击安装。 (说明:ack-onepilot 组件默认支持 1000 个 pod 规模,集群 pod 每超过 1000 个,ack-onepilot 资源对应的 CPU 请增加 0.5 核、内存请增加 512M。)

  5. 在弹出的页面中可以配置相关的参数,建议使用默认值,单击确定。 (说明:安装完成后,您可以在组件管理页面升级、配置或卸载 ack-onepilot 组件。)

步骤二:修改 Dockerfile

  1. 首先从 pypi 仓库下载探针安装器
pip3 install aliyun-bootstrap
  1. 使用 aliyun-bootstrap 安装探针
aliyun-bootstrap -a install
  1. 使用阿里云 python 探针启动
aliyun-instrument python app.py
  1. 构建镜像,具体的 Dockerfile 示例如下:

Dockerfile 示例:

更改前的 Dockerfile:

# 使用Python 3.10基础镜像
FROM docker.m.daocloud.io/python:3.10

# 设置工作目录
WORKDIR /app

# 复制requirements.txt文件到工作目录
COPY requirements.txt .

# 使用pip安装依赖
RUN pip install --no-cache-dir -r requirements.txt

COPY ./app.py /app/app.py
# 暴露容器的8000端口
EXPOSE 8000
CMD ["python","app.py"]

更改后的 Dockerfile:

# 使用官方的Python 3.10基础镜像
FROM docker.m.daocloud.io/python:3.10

# 设置工作目录
WORKDIR /app

# 复制requirements.txt文件到工作目录
COPY requirements.txt .

# 使用pip安装依赖
RUN pip install --no-cache-dir -r requirements.txt
#########################安装aliyun python 探针###############################
RUN pip3 install  aliyun-bootstrap  && aliyun-bootstrap -a install
##########################################################

COPY ./app.py /app/app.py


# 暴露容器的8000端口
EXPOSE 8000
#########################################################
CMD ["aliyun-instrument","python","app.py"]

注意事项(必看)

  1. 有使用 unicorn 启动的应用推荐使用以下命令做替换:

例如:

unicorn -w 4 -b 0.0.0.0:8000 app:app

更改为:

gunicorn -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 app:app
  1. 有使用 gevent 协程的需要配置参数

程序中有使用

from gevent import monkey

monkey.patch_all()

需要设置环境变量 GEVENT_ENABLE=true

GEVENT_ENABLE=true

步骤三:授予 ARMS 资源的访问权限

  • 如果需监控 ASK(容器服务 Serverless 版)或对接了 ECI 的集群应用,请在云资源访问授权 [ 2] 页面完成授权,然后重启 ack-onepilot 组件下的所有 Pod。
  • 如果需监控 ACK 集群应用,但 ACK 集群中不存在 ARMS Addon Token,请执行以下操作手动为集群授予 ARMS 资源的访问权限。如果已经存在 ARMS Addon Token,请跳转至步骤四。

查看集群是否存在 ARMS Addon Token:

a. 登录容器服务管理控制台,在集群列表页面,单击目标集群名称进入集群详情页。
b. 在左侧导航栏选择配置管理 > 保密字典,然后在顶部选择命名空间为kube-system,查看addon.arms.token是否存在。

说明:集群存在 ARMS Addon Token 时,ARMS 会进行免密授权。Kubernetes 托管版集群默认存在 ARMS Addon Token,但对于部分早期创建的 Kubernetes 托管版集群,可能会存在没有 ARMS Addon Token 的情况,因此,对于 Kubernetes 托管版集群,建议首先检查 ARMS Addon Token 是否存在。若不存在,需进行手动授权。

  1. 登录容器服务管理控制台。

  2. 在左侧导航栏选择集群,然后单击目标集群名称。

  3. 在目标集群的集群信息页面单击集群资源页签,然后单击 Worker RAM 角色右侧的链接。

  4. 在角色页面的权限管理页签上,单击新增授权。

  5. 选择权限为 AliyunARMSFullAccess,然后单击确定。 (如果需要监控专有版集群和注册集群应用,请确认对应的阿里云账号已包含 AliyunARMSFullAccess 和 AliyunSTSAssumeRoleAccess 权限。添加权限的操作,请参见为 RAM 用户授权 [ 3]

安装 ack-onepilot 组件后,还需要在 ack-onepilot 中填写有 ARMS 权限的阿里云账号 AK/SK。

  1. 在左侧导航栏选择应用 > Helm 页面,单击 ack-onepilot 组件右侧的更新。

  2. 将 accessKey 和 accessKeySecret 替换为当前账号的 AccessKey,然后单击确定。 (说明:获取 AccessKey 的操作,请参见创建 AccessKey [ 4] 。)

  3. 重启应用 Deployment。

步骤四:为 Python 应用开启 ARMS 应用监控

  1. 在容器服务管理控制台左侧导航栏单击集群,在集群列表页面上的目标集群右侧操作列单击应用管理。

  2. 在无状态页面的目标应用右侧选择更多 > 查看 YAML。 (如需创建一个新应用,单击右上角的使用 YAML 创建资源。)

  3. 在 YAML 文件中将以下 labels 添加到 spec.template.metadata 层级下。

labels:
  aliyun.com/app-language: python # Python应用必填,标明此应用是Python应用。
  armsPilotAutoEnable: 'on'
  armsPilotCreateAppName: "<your-deployment-name>"    #应用在ARMS中的展示名称。

创建一个无状态(Deployment)应用并开启 ARMS 应用监控的完整 YAML 示例模板如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: arms-python-client
  name: arms-python-client
  namespace: arms-demo
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: arms-python-client
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: arms-python-client
        aliyun.com/app-language: python # Python应用必填,标明此应用是Python应用。
        armsPilotAutoEnable: 'on'
        armsPilotCreateAppName: "arms-python-client"    #应用在ARMS中的展示名称。
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/arms-default/python-agent:arms-python-client
          imagePullPolicy: Always
          name: client
          resources:
            requests:
              cpu: 250m
              memory: 300Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

---

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: arms-python-server
  name: arms-python-server
  namespace: arms-demo
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: arms-python-server
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: arms-python-server
        aliyun.com/app-language: python # Python应用必填,标明此应用是Python应用。
        armsPilotAutoEnable: 'on'
        armsPilotCreateAppName: "arms-python-server"    #应用在ARMS中的展示名称。
    spec:
      containers:
        - env:
          - name: CLIENT_URL
            value: 'http://arms-python-client-svc:8000'
        - image: registry.cn-hangzhou.aliyuncs.com/arms-default/python-agent:arms-python-server
          imagePullPolicy: Always
          name: server
          resources:
            requests:
              cpu: 250m
              memory: 300Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

---

apiVersion: v1
kind: Service
metadata:
  labels:
    app: arms-python-server
  name: arms-python-server-svc
  namespace: arms-demo
spec:
  internalTrafficPolicy: Cluster
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  ports:
    - name: http
      port: 8000
      protocol: TCP
      targetPort: 8000
  selector:
    app: arms-python-server
  sessionAffinity: None
  type: ClusterIP

apiVersion: v1
kind: Service
metadata:
  name: arms-python-client-svc
  namespace: arms-demo
  uid: 91f94804-594e-495b-9f57-9def1fdc7c1d
spec:
  internalTrafficPolicy: Cluster
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  ports:
    - name: http
      port: 8000
      protocol: TCP
      targetPort: 8000
  selector:
    app: arms-python-client
  sessionAffinity: None
  type: ClusterIP
上一篇:Unable to open nested entry ‘********.jar‘ 问题解决


下一篇:用 CSS 和 JS 打造简约又不失亮点的客户评价展示-正文