华为云用户手册

  • 使用FunctionGraph部署AI绘画ComfyUI/ComfyUI+FLUX资源和成本规划 本实践根据使用需求的不同,涉及的计费服务有所不同,请参考表1根据具体需求规划资源与成本。 表1 资源和成本规划 资源 资源说明 计费说明 是否必须 函数工作流 FunctionGraph 函数类型:容器镜像HTTP函数 区域:华东-上海一 购买量:2(应用创建成功后自动生成函数) 计费模式:按需计费。 函数工作流提供免费试用,每月前100万次调用免费。具体计费项及说明请参考函数工作流按需计费说明。 必须。 虚拟私有云 VPC 区域:华东-上海一 子网数量:1 安全组数量:1 购买量:1 虚拟私有云:免费。 子网:免费。 安全组:免费。 必须。 API网关 APIG 版本:专享版API网关 区域:华东-上海一 公网入口:开启 购买量:1 计费模式:本例使用按需计费。 实例规格和入公网带宽请根据业务需求选择,具体计费项及标准请参考专享版APIG按需计费说明。 必须。 弹性文件服务 SFS 区域:华东-上海一 文件系统类型:SFS Turbo文件系统 在售 类型:本例使用250MB/S/TiB 容量:1.2 TB 购买量:1 计费模式:本例使用按需计费。 具体计费项请参考弹性文件服务按需计费说明,价格详情请参见弹性文件服务价格详情。 上传和使用自定义模型和自定义节点时必须。 弹性云服务器 E CS 区域:华东-上海一 操作系统:公共镜像 EulerOS 2.5 64bit(40GiB) 购买量:1 计费模式:本例使用按需计费。 实例类型、存储规格请根据业务需求选择,具体计费项及标准请参考弹性云服务器按需计费说明,价格详情请参见弹性 云服务器价格 详情。 使用ECS作为NFS服务器时必须。 NAT网关 NAT 网关类型:公网NAT网关 区域:华东-上海一 规格:小型 购买量:1 计费模式:本例使用按需计费。 规格请根据业务需求选择,具体计费项及标准请参考NAT网关按需计费说明。 使用ComfyUI Manager在线安装自定义模型和自定义节点时必须。 弹性公网IP EIP 区域:华东-上海一 线路:全动态BGP 购买量:1 计费模式:本例使用按需计费。 公网带宽:按流量计费。 具体计费项及标准请参考弹性公网IP按需计费说明。 使用ComfyUI Manager在线安装自定义模型和自定义节点时必须。 父主题: 使用FunctionGraph部署AI绘画ComfyUI/ComfyUI+FLUX应用
  • 步骤一:下载程序包 本例使用Java语言实现日志打印,请下载Log_demo.jar样例代码直接使用,无需其他修改。 关键示例代码如下所示,可参考了解。 package org.example; import com.huawei.services.runtime.Context; import lombok.extern.slf4j.Slf4j; import org.apache.logging.log4j.core.config.Configurator; import org.apache.logging.log4j.util.LoaderUtil; import java.net.URISyntaxException; import java.util.Objects; @Slf4j public class LogTest { public void init(Context context) { try { Configurator.reconfigure(Objects.requireNonNull(LoaderUtil.getThreadContextClassLoader().getResource("log4j2-custom.xml")).toURI()); } catch (URISyntaxException e) { throw new RuntimeException(e); } } public void handler(String event, Context context) { log.debug("debug log"); log.info("info log"); log.warn("warn log"); log.error("info log"); } }
  • 创建Next.js项目 本案例以Next.js框架的默认demo为例演示部署过程,需要在Linux环境中创建一个全新的Next.js项目,本案例采用本地运行Docker node:18.15.0镜像的方式,同样适用于其他Linux系统。关于Docker镜像和Linux操作系统的使用并非本案例主要内容,不做过多赘述。 启动Docker容器并进入code目录(原生Linux系统忽略)。 docker run -it --network=host -v D:/code/nextjs/:/code node:18.15.0 bash cd code 在控制台执行以下命令来创建一个Next.js框架demo工程: npx create-next-app@13.5.6 回车后等待出现该提示词“√ What is your project named? ...”后输入项目名称,如:nextjs-app。 后续提示可以保持默认,或根据您的实际业务情况修改即可。 等待项目创建完成。 图1 项目创建成功 进入项目目录。 cd nextjs-app 官方默认Demo代码需要修改项目中layout.tsx(该文件在nextjs-app下的app目录)文件的代码,不然会导致无法下载字体文件的错误,参见图2并删除红框标出的内容。 图2 删除相关代码 构建项目。 npm run build 图3 构建项目 构建完成后目录内容如下: 图4 项目构建成功后目录内容 创建启动脚本。 创建名为“bootstrap”的启动脚本,并修改bootstrap文件内容如下: export PATH=/opt/function/runtime/nodejs18.15/rtsp/nodejs/bin:$PATH && export npm_config_cache=/tmp/cache && cd /opt/function/code/ && PORT=8000 npm start 打包函数代码。 将目录中的“.next”、“public”、“package.json”和“bootstrap”打包成zip压缩包,本案例命名为“nextjs-func-code.zip”作为函数代码备用。 父主题: 使用Next.js项目构建HTTP函数
  • 步骤一:创建多用户配置文件 本示例以两个用户user1和user2的使用场景进行介绍,可根据实际需要增减用户数。 选择任一用户,进入已完成初始化自定义模型的Stable Diffusion应用详情界面,单击“上传模型”,登录后进入文件系统。 如图1所示,进入sd目录。 图1 进入sd目录 如图2所示,找到config.json文件,选中并复制到任意目录,此处仍置于sd目录下,重命名为config_user1.json。如图3所示,同样为用户user2复制一份,命名为config_user2.json。 图2 复制config.json文件 图3 复制生成config_user1.json和config_user2.json文件
  • 前提条件 每位用户的FunctionGraph云服务委托中需包含“SWR Admin”、“VPC Administrator”、“Server Administrator”、“SFS FullAccess”和“SFS Turbo FullAccess”权限。 每位用户均需完成部署和使用AI绘画Stable Diffusion应用步骤,应用创建成功。 每位用户均需使用同一个SFS文件系统完成初始化自定义模型挂载文件系统,所挂载的SFS文件系统下已存在sd目录。
  • 步骤二:配置 域名 解析 应用创建成功后,如图1所示单击应用详情界面域名提示中的“去绑定”,弹出API网关的管理控制台页面。 图1 进入绑定界面 在弹出的API网关的管理控制台页面中,如图2所示,选择“概览”标签,单击复制“子域名”以备用。 图2 复制子域名 登录 云解析服务DNS 控制台,如图3所示,选择“公网域名”页签,单击已购买的域名所在行右侧的“管理解析”。 如果使用非华为云注册的域名,可参考创建非华为云注册的域名进行操作。 图3 管理解析 如图4所示,在“解析记录”页签下,单击“添加记录集”。 图4 添加记录集 在右侧弹出的“添加记录集”窗口配置以下信息: 记录类型:选择“CNAME - 将域名指向另外一个域名”。 主机记录:请参考添加CNAME类型记录集填写。 记录值:2复制的子域名。 其他配置保持默认即可,如图5所示填写完成后单击“确定”即可完成域名解析。 图5 配置记录集信息
  • 使用API模式访问应用并启用WebUI认证 如需同时使用API模式访问应用和启用WebUI认证,环境变量内容可参考表2设置。 表2 使用API模式访问应用并启用WebUI认证 键 值 说明 EXTRA_ARGS --api --api-auth user1:password1 --gradio-auth user1:password1 “user1”处填写用户名,“password1”处填写需要设置的密码,如多用户使用场景,可通过英文逗号(,)分隔用户名和密码。
  • 步骤四:上传与加载模型 返回应用详情页,单击“开始使用”进入WebUI界面。函数会自动在挂载目录中创建应用所需目录和文件。 页面成功加载后,返回应用详情页,单击“上传模型”打开文件管理工具,默认用户名和密码均为“admin”,登录后请在“设置”页签修改密码,保证数据安全。与应用相关的sd目录内容如图8所示。 图8 文件管理工具 将模型、插件等文件分别上传至对应目录。部分关键目录可参考表3。 重新加载Stable Diffusion WebUI界面,即可看到新传入的模型。 单击右上角“生成”开始进行AI绘画,如图9所示,结果图片会自动保存到“/home/user1/share/sd/outputs/txt2img/202x-xx-xx”目录下。 图9 图片保存目录
  • 步骤一:购买ECS服务器 进入购买ECS服务器页面,购买过程中请参照以下注意事项。实例类型和是否开启公网访问可根据业务需要自行选择,其他参数可参考设置ECS购买参数。 基础配置:如图1所示,本示例使用“按需计费”,区域选择“华东-上海一”。 图1 基础配置 操作系统:本示例镜像选用EulerOS 2.5 64bit(40GiB)。 不同镜像版本下,部分Linux命令可能存在差异。 储存与备份:鉴于多数模型文件的大小在1GB到10GB以上,建议依据具体需求选择系统盘容量,并参考图2 系统盘选择新增数据盘进行挂载。 图2 系统盘选择 网络:虚拟私有云与主网卡请选择创建 虚拟私有云VPC 和子网中所创建VPC与子网,如图3所示。 图3 网络配置 安全组:请参考图4新建安全组,入方向规则允许子网内IP访问端口111、2049、2051、2052、20048以支持NFS服务;其他端口,如22端口用于SSH和SFTP、21端口用于FTP等,具体协议端口和源地址请根据实际需要配置。 图4 安全组设置
  • 免责声明 本应用使用到的Stable-Diffusion、Stable-Diffusion-WebUI以及镜像构建工程等项目均为社区开源项目,关于开源项目的问题还需用户到开源社区寻求帮助或者自行解决,华为云仅提供算力支持。 本实践仅作为简易示例供用户参考和学习,如需应用于实际生产环境,请参考镜像构建工程自行完善和优化。使用过程中遇到的函数工作流问题,可通过提交工单进行咨询。 本应用部署后会为您创建APIG网关,根据有关规定,建议在应用创建成功后根据提示绑定自定义域名,使用您的自有域名访问WebUI界面。 父主题: 使用FunctionGraph部署AI绘画Stable Diffusion应用
  • 步骤三:初始化自定义模型挂载文件系统 登录函数工作流控制台,区域选择“华东-上海一”。在左侧导航栏选择“应用中心”,单击创建成功且需初始化的应用名称,进入应用详情页面。 在应用详情页面,如图1所示单击“初始化自定义模型”,请仔细阅读弹出的说明后进行勾选操作,单击“确定”弹出初始化窗口。 图1 初始化自定义模型 在“初始化自定义模型”窗口填写如下参数: VPC:选择“vpc-fg(192.168.x.x/16)”。 子网:选择“subnet-fg(192.168.x.x/24)”。 文件系统来源:选择“SFS Turbo”。 文件系统名称:选择“sfs-turbo-fg”。 其他参数保持默认,如图2所示,配置完成后单击“确定”。 图2 初始化自定义模型 返回应用详情界面,“初始化自定义模型”按键变更为“上传模型”按键即初始化成功,单击“开始使用”进入WebUI界面,系统将在文件系统中自动创建与部署应用所需的目录和文件。 成功进入Stable Diffusion WebUI界面后无需进行操作,此操作用于加载文件系统中的目录和文件,便于后续上传自定义模型。
  • 步骤四:上传与加载自定义模型 返回应用详情界面,单击“上传模型”进入文件管理页面,默认用户名和密码均为“admin”,登录后请在“设置”页签修改密码,保证数据安全。 与上传自定义模型相关的部分关键目录如表3所示,可将模型文件上传到对应目录下。 表3 部分关键目录路径 路径 用途 sd/models/Stable-diffusion 保存checkpoint模型文件。 sd/models/VAE 保存VAE模型文件。 sd/models/Lora 保存Lora模型文件。 sd/extensions 保存插件。 sd/outputs 保存生成结果。 上传完成后,返回Stable Diffusion WebUI界面,如图3所示,单击页面中相应的“刷新”按钮加载模型,或重新打开WebUI界面。加载成功后即可查看和选择新增模型进行AI绘画。加载过程可能耗时较长,请耐心等待。 图3 加载模型
  • 步骤一:创建虚拟私有云VPC和子网 登录华为云网络控制台,单击“创建虚拟私有云”,进入“创建虚拟私有云”界面。 在“创建虚拟私有云”界面参考表1填写参数,其他参数保持默认即可。 表1 VPC和子网参数配置 参数类别 参数 参数说明 取值样例 基本信息 区域 必选参数。 VPC及其子网部署的区域。当前Stable Diffusion应用仅支持在“华东-上海一”部署。 华东-上海一 名称 必选参数。 VPC的名称。要求如下: 长度范围为1~64位。 名称由中文、英文字母、数字、下划线(_)、中划线(-)、点(.)组成。 vpc-fg IPv4网段 必选参数。 设置VPC的IPv4网段范围,可以根据页面建议选择,VPC网段的选择需要考虑以下两点: IP地址数量:要为业务预留足够的IP地址,防止业务扩展给网络带来冲击。 IP地址网段:当前VPC与其他VPC、云下数据中心连通时,要避免网络两端的IP地址冲突,否则无法正常通信。 192.168.x.x/16 企业项目 必选参数。 企业项目管理提供了一种按企业项目管理云资源的方式,帮助您实现以企业项目为基本单元的资源及人员的统一管理,默认项目为default。 default 子网设置1 子网名称 必选参数。 子网的名称。要求如下: 长度范围为1~64位。 名称由中文、英文字母、数字、下划线(_)、中划线(-)、点(.)组成。 subnet-fg 可用区 必选参数。 在同一VPC网络内可用区与可用区之间内网互通,可用区之间能做到物理隔离。如业务需求高推荐选择多个可用区,本例以选择一个可用区为例。 可用区1(center) 子网IPv4网段 必选参数。 子网的IPv4网段范围。子网的网段必须在VPC网段范围内,子网网段的掩码长度范围为“子网所在VPC的掩码~29”,可以根据页面建议选择。 192.168.x.x/24 参数配置完成后,单击“立即创建”,完成虚拟私有云VPC和子网的创建。
  • 步骤二:创建SFS Turbo文件系统 登录华为云弹性文件服务控制台,选择“SFS Turbo”,单击“创建文件系统”,进入“创建文件系统”界面。 在“创建文件系统”界面,参考表2填写参数。其他参数保持默认即可,如需使用其他参数请参考创建SFS Turbo文件系统。 表2 文件系统参数说明 参数 参数说明 取值样例 计费模式 必选参数。 按需计费:适用于灵活使用场景。 包年/包月:适用于可预估资源使用周期的场景。 按需计费 区域 必选参数。 文件系统部署的区域。当前AI绘画应用仅支持在“华东-上海一”部署,且需与创建的虚拟私有云VPC保持一致。 华东-上海一 项目 必选参数。 项目部署的区域。根据区域选择默认同步设置。 华东-上海一(默认) 可用区 必选参数。 与创建的子网可用区保持一致。 可用区1 类型 必选参数。 根据推荐场景和实际情况选择文件系统类型和性能。本例支持选择所有文件系统类型,推荐选择适合大多数使用场景的 250 MB/s/TiB类型。 250 MB/s/TiB 容量 必选参数。 单个文件系统的最大容量。请根据实际需求选择,输入值应位于1.2至1023.6的区间内且必须为1.2的整数倍。 1.2 企业项目 必选参数。 与创建虚拟私有云VPC时的选择保持一致。 default 选择网络 必选参数。 文件系统所属的VPC和子网。选择创建虚拟私有云VPC和子网中创建的VPC与子网。 vpc-fg; subnet-fg(192.168.x.x/24) 名称 必选参数。 文件系统的名称。要求如下: 长度范围为4~64位,并以字母开头。 只能由英文字母、数字、下划线“_”和中划线“-”组成。 sfs-turbo-fg 参数配置完成后,单击“立即创建”,再次确认信息后单击“提交”,等待文件系统创建任务提交成功即可。
  • 配置函数代码执行返回结果 如果没有对函数代码执行返回结果有特定要求,例如绑定了APIG触发器的事件函数需要返回一个APIG响应格式的结果如下: import json def handler (event, context): return { "statusCode": 200, "isBase64Encoded": False, "body": json.dumps(event), "headers": { "Content-Type": "application/json" } } 一般不建议在函数代码内捕获异常,其会导致创建的错误次数告警配置不生效。但是FunctionGraph实现了与 云日志 服务(LTS)的对接,支持在LTS服务中配置告警,LTS支持日志告警实时监控函数日志中出现的异常信息。
  • FunctionGraph监控告警 Redis自动重试机制能大幅度降低暂时性故障影响,但不能解决故障,故障不及时处理可能导致故障升级,所以需要告警来及时感知代码运行情况。FunctionGraph支持通过创建告警规则完成对函数运行的实时监控,当函数指标出现满足设定规则时产生告警,通过短信或邮件的方式通知用户。客户收到告警后,可以配置和查看函数的调用日志来分析故障原因,解决故障。 FunctionGraph函数监控信息,提供了调用次数、运行时间、错误次数、拒绝次数和资源统计监控指标。建议对监控指标中的错误次数和运行时间-最大运行时间创建告警配置,这样就能及时感知到如下情况: 访问Redis异常。例如连接异常、请求超时、服务暂时不可用,导致函数执行错误计入错误次数指标。 使用复杂度过高命令,导致CPU耗尽,函数执行时间变长,体现在运行时间-最大运行时间指标。 父主题: 使用FunctionGraph函数访问Redis数据
  • 配置Redis定时健康检查 Redis健康检查的作用是判断Redis服务端是否正常工作,使用health_check_interval配置对Redis进行定时健康检查,该配置单位为秒,默认值为0不进行健康检查,代码如下: retry = Retry(ExponentialBackoff(), 3) pool = BlockingConnectionPool(host=redis_host, port=redis_port, password=redis_password, max_connections=50, timeout=3, socket_timeout=2, socket_connect_timeout=2, retry=retry, retry_on_error=[BusyLoadingError, ConnectionError, TimeoutError], health_check_interval=60, decode_responses=True) 如果业务量大建议不使用该配置,进而减少开销。
  • Redis重试机制 Redis客户端支持添加自动重试机制,确保在执行Redis操作失败后重试特定次数,这样能大幅度降低暂时性故障影响。例如:发生瞬时的网络抖动、磁盘抖动导致服务暂时不可用或者调用超时的情况下,提高Redis操作的成功概率。 连接DCS单机、主备、读写分离、Proxy集群实例添加Retry配置,退避策略为指数退避(ExponentialBackoff),重试次数上限为3次,并通过retry_on_error配置指定了BusyLoadingError,ConnectionError,TimeoutError三种错误才进行重试,代码片段如下: retry = Retry(ExponentialBackoff(), 3) pool = BlockingConnectionPool(host=redis_host, port=redis_port, password=redis_password, max_connections=50, timeout=3, socket_timeout=2, socket_connect_timeout=2, retry=retry, retry_on_error=[BusyLoadingError, ConnectionError, TimeoutError], health_check_interval=60, decode_responses=True) 连接DCS集群实例使用了集群错误重试配置(cluster_error_retry_attempts),当遇到TimeoutError、ConnectionError或ClusterDownError时进行重试,默认重试上限为3,代码如下: client = Redis(host=redis_host, port=redis_port, password=redis_password, cluster_error_retry_attempts=3, health_check_interval=60, max_connections=50, decode_responses=True) 可以搭配Retry一起使用,示例代码如下: from redis.backoff import ExponentialBackoff from redis.retry import Retry from redis.cluster import RedisCluster rc = RedisCluster(host='localhost', port=6379, retry=Retry(ExponentialBackoff(), 6), cluster_error_retry_attempts=1) 但是其最大重试次数为 retries * (cluster_error_retry_attempts+1),以上述示例代码为例,最大重试次数为12次。 父主题: 代码解读
  • Redis连接池 在示例代码中使用了Redis连接池(BlockingConnectionPool),配置了最大连接数(max_connections)和连接池耗尽后获取连接的最大等待时间(timeout),代码片段如下: pool = BlockingConnectionPool(host=redis_host, port=redis_port, password=redis_password, max_connections=50, timeout=3, socket_timeout=2, socket_connect_timeout=2, retry=retry, retry_on_error=[BusyLoadingError, ConnectionError, TimeoutError], health_check_interval=60, decode_responses=True) 使用Redis连接池进一步复用已创建的连接,有效提升程序性能;同时,Redis提供了最大连接数配置确保连接资源的使用保持在一个可控范围内,并且能够确保线程安全。 最大连接数配置区间:在FunctionGraph函数配置Redis最大连接数建议在如下区间选取一个值: 最大连接数下限 =(函数单实例并发度)*(函数单次执行访问Redis并发度) 最大连接数上限 =(Redis实例连接数上限)/(函数最大实例数) 举例:某个访问Redis函数单实例并发度配置为5,每次执行函数访问Redis并发度为2,函数最大实例数默认400,访问的Redis实例连接数上限为30000,计算如下: 最大连接数下限 = 5*2 = 10 最大连接数上限 = 30000/400 = 75 按上述结果,建议最大连接数配置50即可。 连接池耗尽后获取连接的最大等待时间:不要超过函数执行超时时间,避免因连接池耗尽后获取连接等待导致函数执行超时。如果需要快速失败将BlockingConnectionPool替换成ConnectionPool,并删除timeout配置即可。 父主题: 代码解读
  • FunctionGraph函数初始化入口 在示例代码中,initializer方法内创建Redis客户端,并在创建函数时配置了初始化函数,如下: def initializer(context): global redis_client redis_client = create_redis_client(context) redis_client.ping() 图1 初始化函数配置 这里用到了FunctionGraph的函数初始化入口Initializer能力,通过该能力能在函数初始化阶段完成Redis客户端的创建,在调用handler处理请求时能够使用该Redis客户端复用连接,相比在handler处理请求时每次都创建Redis客户端,减少了资源消耗并且性能更优。 请勿在函数初始化入口捕获异常,否则会导致FunctionGraph认为函数初始化成功,进而开始接收函数调用请求。但是因为初始化实际上是失败的,导致函数执行时使用了不可用的redis_client而失败。 父主题: 代码解读
  • 连接DCS集群实例 from redis.cluster import RedisCluster as Redis from redis.cluster import ClusterNode redis_client = None def create_redis_client(context): logger = context.getLogger() redis_cluster_nodes = context.getUserData( "redis_ip_address") redis_password = context.getUserData( "redis_password") startup_nodes = [] for redis_node in redis_cluster_nodes.split(','): node_info = redis_node.split(":") startup_nodes.append(ClusterNode(host=node_info[0], port=node_info[1])) logger.info("redis startup_nodes={}".format(startup_nodes)) client = Redis(startup_nodes=startup_nodes, password=redis_password, cluster_error_retry_attempts=3, socket_timeout=2, socket_connect_timeout=2, health_check_interval=60, max_connections=50, decode_responses=True) return client def initializer(context): global redis_client redis_client = create_redis_client(context) redis_client.ping() def handler(event, context): logger = context.getLogger() redis_client.set('foo', 'bar') value = redis_client.get('foo') logger.info("redis get key foo value={}".format(value)) return value 表1 RedisCluster配置 参数 默认值 说明 host localhost 连接Redis实例的IP地址/域名 port 6379 连接端口号 cluster_error_retry_attempts 3 当遇到TimeoutError、ConnectionError或ClusterDownError时,在抛出异常之前重试的次数 其他参数配置可以参考表3。 父主题: 示例代码
  • 连接DCS单机、主备、读写分离、Proxy集群实例 from redis.backoff import ExponentialBackoff from redis.retry import Retry from redis.client import Redis from redis.connection import BlockingConnectionPool from redis.exceptions import ( BusyLoadingError, ConnectionError, TimeoutError ) redis_client = None def create_redis_client(context): logger = context.getLogger() redis_address = context.getUserData("redis_ip_address") redis_host = redis_address.split(":")[0] redis_port = redis_address.split(":")[1] redis_password = context.getUserData("redis_password") logger.info("redis host={}".format(redis_host)) logger.info("redis port={}".format(redis_port)) retry = Retry(ExponentialBackoff(), 3) pool = BlockingConnectionPool(host=redis_host, port=redis_port, password=redis_password, max_connections=20, timeout=3, socket_timeout=2, socket_connect_timeout=2, retry=retry, retry_on_error=[BusyLoadingError, ConnectionError, TimeoutError], health_check_interval=60, decode_responses=True) return Redis(connection_pool=pool) def initializer(context): global redis_client redis_client = create_redis_client(context) redis_client.ping() def handler(event, context): logger = context.getLogger() redis_client.set('foo', 'bar') value = redis_client.get('foo') logger.info("redis get key foo value={}".format(value)) return value 客户端使用连接池时不要将获取连接的操作放在初始化函数 initializer 方法中,否则只会在初始化时获取一个连接而导致连接池使用无效。当网络抖动时可能会使已获取的连接断连,后续复用该实例的并发请求时可能会因断连而访问redis失败。 表1 Redis配置 参数 默认值 说明 connection_pool None 连接池 表2 BlockingConnectionPool配置 参数 默认值 说明 max_connections 50 连接池最大连接数 timeout 20 连接池耗尽后获取连接的最大等待时间 表3 Connection配置 参数 默认值 说明 host localhost 连接Redis实例的IP地址/域名 port 6379 连接端口号 password - 连接密码 socket_timeout None 请求等待响应的超时时间(秒) socket_connect_timeout None 连接超时时间(秒) retry None 失败后重试策略 retry_on_error None 需要重试的错误列表 health_check_interval 0 Redis连接健康检查间隔 decode_responses False 默认所有响应都以字节形式返回 表4 Retry配置 参数 默认值 说明 backoff - 退避策略 retries - 重试次数,可以是负数,支持永远重试 supported_errors ConnectionError TimeoutError socket.timeout 触发重试的支持错误类型 表5 ExponentialBackoff配置 参数 默认值 说明 cap 0.512 最大退避时间(秒) base 0.008 基本退避时间(秒) 父主题: 示例代码
  • 实现流程 表1 使用FunctionGraph函数访问Redis数据实现流程 序号 步骤 说明 1 准备工作 使用FunctionGraph配置函数访问Redis数据前需进行的前期准备。 2 创建依赖包 创建一个redis-py的依赖包。 3 创建函数 创建实现Redis数据访问的函数并进行配置。请参考示例代码连接实例。 4 FunctionGraph监控告警 创建FunctionGraph监控告警完成对函数运行的实时监控。 5 日志告警(可选) 配置函数代码执行日志告警结果返回。 6 调试函数 配置测试事件进行函数调试。
  • 创建功能函数 创建实现日志提取功能的函数,将示例代码包上传。创建过程请参考创建事件函数,运行时语言选择“Python3.9”,委托名称选择创建委托中的“LtsOperation”。 创建函数A,代码样例请参考write_log.py。函数A代码中host、log_group_id和log_stream_id使用对应接入点和创建好的日志组test-1206、日志流test-206的ID,如图2所示。 图2 write_log.py 创建函数B,代码样例请参考lts_cleanse.py。函数B代码中host、log_group_id和log_stream_id使用对应接入点和创建好的日志组test-1121、日志流test-1121的ID,并为函数B添加依赖huaweicloudsdklts,如图3和图4所示。 图3 lts_cleanse.py 图4 为函数B添加依赖包 函数实现的功能是:将收到的日志事件数据进行base64解码,然后提取出包含“WRN”、“WARN”、“ERR”或“ERROR”关键字的告警日志,将此级别的日志投递至创建好的LTS日志流中集中存储。可根据您的业务日志的具体内容配置相应的日志提取条件。
  • 创建委托 登录 统一身份认证 服务控制台。 在统一身份认证服务的左侧导航窗格中,选择“委托”菜单,单击右上方的“+创建委托”,如图2所示。 图2 创建委托 开始配置委托。 委托名称:输入您自定义的委托名称,此处以“LtsOperation”为例。 委托类型:选择“云服务”。 云服务:选择“函数工作流 FunctionGraph”。 持续时间:选择“永久”。 描述:填写描述信息。 单击“下一步”,进入委托权限选择页面,在右方搜索框中搜索并勾选“LTS Administrator”权限。 选择“LTS Administrator”,由于该策略有依赖,在勾选LTS Administrator时,还会自动勾选依赖的策略:Tenant Guest。 单击“下一步”,根据实际业务需求选择资源授权范围,单击“确定”,完成权限委托设置。
  • 日志采集和存储 在云日志服务创建日志组,此处以test1206、test-1121为例,创建过程请参考创建日志组。 在云日志服务创建日志流,此处以test-206、test-1121为例,创建过程请参考创建日志流。 创建函数A,负责写入日志到test-206。函数A代码样例请参考write_log.py。 创建函数B,挂载LTS触发器,接收test-206的日志,处理日志并发结果写入test-1121。函数B代码样例请参考lts_cleanse.py。 在云日志服务配置Agent,快速将ECS等服务器上日志采集到指定的日志组,配置过程请参考安装ICAgent。 图1 流程图
  • 测试函数 测试托管方式改造函数,调用方法如图1所示。 图1 测试函数调用的方法 调用时,遵循原来的请求方法。 请求url为添加事件源创建的APIG触发器地址。 需要在headers里配置requestPath,值为图1中的@Path(可能会包含一些服务前缀,对应微服务改造之前的请求Path即可),如图2所示。 图2 requestPath配置 测试独立函数。 统一使用POST请求。 请求url为添加事件源创建的APIG触发器地址。 Body体参考如下格式进行配置,如图3所示,在函数代码中可以根据需要,通过APIGTriggerEvent对象获取相应的值。 图3 Body体 { "body": "xxxxxx", "requestContext": { "apiId": "xxxx", "requestId": "xxxxx", "stage": "RELEASE" }, "queryStringParameters": { "responseType": "html" }, "httpMethod": "POST", "pathParameters": {}, "headers": { "accept-language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "accept-encoding": "gzip, deflate, br", "x-forwarded-port": "443", "x-forwarded-for": "xxxxxx", "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "upgrade-insecure-requests": "1", "host": "xxxxxxxx", "x-forwarded-proto": "https", "pragma": "no-cache", "cache-control": "no-cache", "x-real-ip": "xxxxxxxx", "user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0" }, "path": "", "isBase64Encoded": true } 父主题: 使用FunctionGraph函数对MFA微服务进行Serverless化改造
  • 创建函数流 返回函数工作流控制台,在左侧导航栏选择“函数流”,进入函数流列表界面。 单击“创建快速函数流”,进入创建快速函数流流程。 图2 创建快速函数流 拖拽一个函数节点,单击函数节点配置元信息: 应用:默认“default”; 函数:选择上一步创建好的函数test-rotate; 版本:默认“latest”; 其他参数默认值即可。 图3 配置元信息 参数配置完成后,单击“确定”。 函数流节点创建完成后,单击右上角“保存”,配置如下函数流基本信息,完成后单击“确定”,完成函数流创建。 名称:test-rotate-workflow; 企业项目:默认“default”; 日志记录:默认“ALL”; 其他参数保持默认值。 图4 保存函数流
  • 触发函数自动运行 上传文件至dew-bucket-input桶,OBS生成事件触发函数运行,对文件加解密,输出文件存放在dew-bucket-output桶中。可以在fss_examples_dew函数详情页“日志”页签查看函数运行日志。 进入dew-bucket-output桶对象界面,可以看到输出的图片image.jpg.encrypt,如图2所示。单击操作列的“下载”可将文件下载至本地查看处理效果。 图2 输出文件
  • 添加事件源 OBS桶及函数创建以后,可以为函数添加事件源,是通过创建“OBS应用事件源”实现的,步骤如下。 用户进入fss_examples_dew函数详情页,在“触发器”页签,单击“创建触发器”,弹出“创建触发器”界面。 触发器类型选择“OBS应用事件源”,填写触发器配置信息,如图1所示。 桶选择创建OBS桶中创建的“input_bucket”桶。 事件选择“通过页面或Put请求创建或覆盖桶对象”和“使用Post请求创建或覆盖桶对象”。 图1 创建OBS应用事件源 单击“确定”,完成触发器创建。 OBS应用事件源创建以后,当有文件上传或更新至dew-bucket-input桶时,生成事件,触发函数执行。 父主题: 使用FunctionGraph函数对OBS中的文件进行加解密
共100000条
提示

您即将访问非华为云网站,请注意账号财产安全