利用 Amazon API Gateway 和 Amazon Lambda 处理 Cloudfront 的内容请求

0
0
{"value":"### **概述**\n\n国内 Amazon Cloudfront 目前不支持 Lambda@edge 功能,不能实现基于 CDN 的 A/B 测试、rewrite、redirect、token 认证和产生 response 等功能,本文介绍如何利用 API Gateway 和 Lambda 实现 Lambda@edge 的功能。下面实验介绍通过 request header 参数值,实现 redirect 和 rewrite 的测试场景,根据 header(test_version)参数值,回源到指定目录的文件,根据 header(redirect)参数值,返回 302 重定向地址。\n\n整体实验的架构图如下:\n\n![image.png](https://dev-media.amazoncloud.cn/260f1a771c584910a4866a9a83ca01d3_image.png)\n\n架构图说明:\n\n1. Cloudfront 是 Amazon 的 CDN 服务,可以设置源站域名,回源 header,缓存策略等。\n2. API Gateway 有两种类型可以支持 rewrite 和 redirect 测试场景,实验中采用 HTTP API,考虑到成本更低,同时不需要 Rest API 的高级功能。\n3. Lambda 实现了 rewrite 和 redirect 的测试代码,支持验证 security header。支持多种主流语言,实验中采用 Python3.9 语言实现。\n4. S3 保存测试的 html 和 png 文件。\n\n### **详细步骤说明**\n\n#### **1.新建 S3 Bucket**\n\n比如:bucket name:lambda-api-2022\n\n上传文件列表:\n\nindex.html – 欢迎页\n\nv1/test.html – A 测试页\n\nv1/test.png – A 测试图片\n\nv2/test.html – B 测试页\n\nv2/test.png – B 测试图片\n\n#### **2.新建 Lambda 程序**\n\n##### **1)新建 IAM Role,执行 Lambda 程序,比如 Role name:RoleForLambda**\n\n需要的权限如下:\n\n```\n{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \" s3get\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::lambda-api-2022/*\"\n },\n {\n \"Sid\": \" putlogs\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"logs:CreateLogGroup\",\n \"logs:CreateLogStream\",\n \"logs:PutLogEvents\"\n ],\n \"Resource\": \"*\"\n }\n ]\n}\n```\n\n##### **2)创建 Lambda 程序**\n\n采用下列的参数和配置:\n\nFunction name:lambdaapi\n\nRuntime:Python 3.9\n\nExecution role:RoleForLambda(上一步创建的)\n\n修改 Configuration 的配置:\n\n添加 Environment variables\n\n添加 Key=bucket,Value=lambda-api-2022\n\n添加 Key=lambda_auth,Value=lambdaapi_test\n\n添加 Key=redirect_path,Value=https://xxx.cloudfront.net,value 来自下面创建的 Cloudfront distribution\n\nGeneral configuration\n\n修改 Timeout 为20秒\n\nLambda Source Code:\n\n```\nimport boto3\nimport base64\nimport os\n\ns3_client = boto3.client('s3')\n\ndef lambda_handler(event, context):\n\n print(event)\n\n # check security header\n if 'lambda_auth' in event['headers'] and event['headers']['lambda_auth'] == os.environ['lambda_auth']:\n\n bucket = os.environ['bucket']\n \n key = event['rawPath'][1:] # request URI\n \n print(key)\n \n if len(key) == 0:\n key = 'index.html'\n \n # rewrite url\n if 'test_version' in event['headers']:\n key = event['headers']['test_version']+'/'+key\n \n # redirect \n if 'redirect' in event['headers'] and event['headers']['redirect'] == 'true':\n return {\n 'statusCode': 302,\n 'statusDescription': 'Found',\n 'headers': { 'Location': os.environ['redirect_path'] + '/' + key }\n }\n \n # return content body - rewrite\n try:\n response = s3_client.get_object(Bucket = bucket, Key = key)\n responseBody = response['Body'].read() # return bytes from S3\n responseContentType = response['ResponseMetadata']['HTTPHeaders']['content-type']\n return {\n 'headers': { \"Content-Type\": responseContentType },\n 'statusCode': 200,\n 'body': base64.b64encode(responseBody).decode('utf-8'),\n 'isBase64Encoded': True\n }\n except Exception as e:\n print('error message - ', e.__class__.__name__, ' : ', e)\n \n return {\n 'statusCode': 200,\n 'body': 'no file: '+key\n }\n \n else:\n # auth failed\n return {\n 'statusCode': 403,\n 'body': 'request is forbidden'\n }\n```\n\nLambda Source Code 说明:\n\n在 Cloudfront 回源时,添加 lambda_auth header,用于 Lambda 认证请求,当认证失败时,返回 403 错误。\n\n当请求根目录时,返回 index.html\n\n当 request header 包含 test_version 时,转向到指定目录下的文件。\n\n将返回的 body 通过 base64 编码,以支持 binary 对象。\n\n当 request header 包含 redirect=true 时,返回 302 重定向信息。\n\n#### **3.新建 API Gateway**\n\n在 API Gateway 中,新建 HTTP API,比如 API Name:lambdaapi\n\n新建 Lambda integration,选择上一步创建的 Lambda(lambdaapi)\n\n在 Configure routes 时,Resource path 设置为 “/{proxy+}”\n\n在 Deploy Stages中,找到 $default stage 的 Invoke URL,如[https://xxx.execute-api.xxx.amazonaws.com](https://xxx.execute-api.xxx.amazonaws.com/),此为 API Gateway 的请求地址。\n\n测试 API gateway:\n\n- 测试 security header\n\n测试命令:curl [https://xxx.execute-api.xxx.amazonaws.com](https://xxx.execute-api.xxx.amazonaws.com/)\n\n返回结果:request is forbidden\n\n- 测试访问根路径,传入 lambda_auth header\n\n测试命令:curl -v -H “lambda_auth:lambdaapi_test” [https://xxx.execute-api.xxx.amazonaws.com](https://xxx.execute-api.xxx.amazonaws.com/)\n\n返回结果:statusCode=200\n\n- 访问 B 测试页,传入 lambda_auth header和test_version header\n\n测试命令:curl -H “lambda_auth:lambdaapi_test” -H “test_version:v2” [https://xxx.execute-api.xxx.amazonaws.com/test.html](https://xxx.execute-api.xxx.amazonaws.com/test.html)\n\n返回 v2/test.html 的内容\n\n- 访问B测试图片,传入 lambda_auth header 和 test_version header\n\n测试命令:curl -H “lambda_auth:lambdaapi_test” -H “test_version:v2” [https://xxx.execute-api.xxx.amazonaws.com/test](https://xxx.execute-api.xxx.amazonaws.com/test.).png > test.png\n\n将 response 保存为 test.png 图片。\n\n- 测试 redirect,传入 redirect header\n\n测试命令:curl -v -H “lambda_auth:lambdaapi_test” -H “test_version:v1” -H “redirect:true” [https://xxx.execute-api.xxx.amazonaws.com/test.html](https://mgneszib8a.execute-api.xxx.amazonaws.com/test.html)\n\n返回 302 重定向信息\n\n#### **4.配置 Cloudfront**\n\n##### **1)创建 Origin request policy,Amazon Cloud Global支持该功能**\n\n在 Cloudfront Policies 中,新建 origin request policy,例如 Name:lambdaapi\n\n配置如下:\n\nHeaders:选择 Include the following headers,并手工添加 header:test_version和redirect\n\nQuery strings: All\n\nCookies:All\n\n##### **2)创建 Cloudfront Distribution**\n\n在 Cloudfront 中,新建 Distribution,例如 Description:lambdaapi\n\n配置如下:\n\nOrigin domain:xxx.execute-api.xxx.amazonaws.com,上面创建的 HTTP API 域名\n\nProtocol:HTTPS only\n\nAdd custom header:\n\nHeader name = lambda_auth,Value = lambdaapi_test\n\n在 Amazon Cloud Global,支持 Cache policy and origin request policy (recommended),配置下面两个参数:\n\nCache policy:CachingDisabled\n\nOrigin request policy:Custom lambdaapi\n\n或者在 Amazon Cloud China,支持 Legacy cache settings,配置下面 3 个参数:\n\nHeaders:选择 Include the following headers,并手工添加header:test_version和redirect。\n\nQuery strings: All\n\nCookies:All\n\n如果不需要 Cloudfront 缓存内容时,需要设置 Object caching 为Customize,同时将 Minimum TTL、Maximum TTL 和 Default TTL 都设为 0.\n\n注:需新建 origin 和 behavior,配合 redirect 后 Cloudfront 地址。\n\n#### **5.测试 Cloudfront**\n\n1.在 Cloudfront Distributions (Lambdaapi)的 General Details 中,找到 Distribution domain name,例如 cloudfront.net\n\n2.访问 A 测试页,传入 test_version header\n\n测试命令:curl -H “test_version:v1” https://xxx.cloudfront.net/test.html\n\n返回 v1/test.html 的内容\n\n3.测试 redirect,传入 test_version 和 redirect header\n\n测试命令:curl -I -H “test_version:v1” -H “redirect:true” https://xxx.cloudfront.net/test.html\n\n返回 302 重定向的内容\n\n### **结论**\n\n在这篇文章中,介绍了如何利用 API Gateway 和 Lambda 处理Cloudfront 的内容请求,实现 Lambda@edge 的功能,在实验中,介绍了 Amazon S3、Lambda、API Gateway 和 Cloudfront 的配置方法,实现了 rewrite 和 redirect 的测试场景。\n\n### **参考资料**\n\n- [https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html)\n- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html\n- [https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html)\n- [https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-dynamo-db.html](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-dynamo-db.html)\n- [https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.SimpleDistribution.html](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.SimpleDistribution.html)\n- https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.html\n\n### **本篇作者**\n\n![image.png](https://dev-media.amazoncloud.cn/e9e49fa460bd48f58ce15ec693268667_image.png)\n\n#### **薛召兵**\n\nAmazon 解决方案架构师,负责帮助客户进行上云架构的设计和咨询。同时致力于 Amazon 容器服务、媒体服务和机器学习服务在国内和全球商业客户的应用和推广,推进企业服务迁移上云进程。有 10 年以上的软件开发、售前技术支持、系统架构设计等经验。\n","render":"<h3><a id=\"_0\"></a><strong>概述</strong></h3>\n<p>国内 Amazon Cloudfront 目前不支持 Lambda@edge 功能,不能实现基于 CDN 的 A/B 测试、rewrite、redirect、token 认证和产生 response 等功能,本文介绍如何利用 API Gateway 和 Lambda 实现 Lambda@edge 的功能。下面实验介绍通过 request header 参数值,实现 redirect 和 rewrite 的测试场景,根据 header(test_version)参数值,回源到指定目录的文件,根据 header(redirect)参数值,返回 302 重定向地址。</p>\n<p>整体实验的架构图如下:</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/260f1a771c584910a4866a9a83ca01d3_image.png\" alt=\"image.png\" /></p>\n<p>架构图说明:</p>\n<ol>\n<li>Cloudfront 是 Amazon 的 CDN 服务,可以设置源站域名,回源 header,缓存策略等。</li>\n<li>API Gateway 有两种类型可以支持 rewrite 和 redirect 测试场景,实验中采用 HTTP API,考虑到成本更低,同时不需要 Rest API 的高级功能。</li>\n<li>Lambda 实现了 rewrite 和 redirect 的测试代码,支持验证 security header。支持多种主流语言,实验中采用 Python3.9 语言实现。</li>\n<li>S3 保存测试的 html 和 png 文件。</li>\n</ol>\n<h3><a id=\"_15\"></a><strong>详细步骤说明</strong></h3>\n<h4><a id=\"1_S3_Bucket_17\"></a><strong>1.新建 S3 Bucket</strong></h4>\n<p>比如:bucket name:lambda-api-2022</p>\n<p>上传文件列表:</p>\n<p>index.html – 欢迎页</p>\n<p>v1/test.html – A 测试页</p>\n<p>v1/test.png – A 测试图片</p>\n<p>v2/test.html – B 测试页</p>\n<p>v2/test.png – B 测试图片</p>\n<h4><a id=\"2_Lambda__33\"></a><strong>2.新建 Lambda 程序</strong></h4>\n<h5><a id=\"1_IAM_Role_Lambda__Role_nameRoleForLambda_35\"></a><strong>1)新建 IAM Role,执行 Lambda 程序,比如 Role name:RoleForLambda</strong></h5>\n<p>需要的权限如下:</p>\n<pre><code class=\"lang-\">{\n &quot;Version&quot;: &quot;2012-10-17&quot;,\n &quot;Statement&quot;: [\n {\n &quot;Sid&quot;: &quot; s3get&quot;,\n &quot;Effect&quot;: &quot;Allow&quot;,\n &quot;Action&quot;: &quot;s3:GetObject&quot;,\n &quot;Resource&quot;: &quot;arn:aws:s3:::lambda-api-2022/*&quot;\n },\n {\n &quot;Sid&quot;: &quot; putlogs&quot;,\n &quot;Effect&quot;: &quot;Allow&quot;,\n &quot;Action&quot;: [\n &quot;logs:CreateLogGroup&quot;,\n &quot;logs:CreateLogStream&quot;,\n &quot;logs:PutLogEvents&quot;\n ],\n &quot;Resource&quot;: &quot;*&quot;\n }\n ]\n}\n</code></pre>\n<h5><a id=\"2_Lambda__63\"></a><strong>2)创建 Lambda 程序</strong></h5>\n<p>采用下列的参数和配置:</p>\n<p>Function name:lambdaapi</p>\n<p>Runtime:Python 3.9</p>\n<p>Execution role:RoleForLambda(上一步创建的)</p>\n<p>修改 Configuration 的配置:</p>\n<p>添加 Environment variables</p>\n<p>添加 Key=bucket,Value=lambda-api-2022</p>\n<p>添加 Key=lambda_auth,Value=lambdaapi_test</p>\n<p>添加 Key=redirect_path,Value=https://xxx.cloudfront.net,value 来自下面创建的 Cloudfront distribution</p>\n<p>General configuration</p>\n<p>修改 Timeout 为20秒</p>\n<p>Lambda Source Code:</p>\n<pre><code class=\"lang-\">import boto3\nimport base64\nimport os\n\ns3_client = boto3.client('s3')\n\ndef lambda_handler(event, context):\n\n print(event)\n\n # check security header\n if 'lambda_auth' in event['headers'] and event['headers']['lambda_auth'] == os.environ['lambda_auth']:\n\n bucket = os.environ['bucket']\n \n key = event['rawPath'][1:] # request URI\n \n print(key)\n \n if len(key) == 0:\n key = 'index.html'\n \n # rewrite url\n if 'test_version' in event['headers']:\n key = event['headers']['test_version']+'/'+key\n \n # redirect \n if 'redirect' in event['headers'] and event['headers']['redirect'] == 'true':\n return {\n 'statusCode': 302,\n 'statusDescription': 'Found',\n 'headers': { 'Location': os.environ['redirect_path'] + '/' + key }\n }\n \n # return content body - rewrite\n try:\n response = s3_client.get_object(Bucket = bucket, Key = key)\n responseBody = response['Body'].read() # return bytes from S3\n responseContentType = response['ResponseMetadata']['HTTPHeaders']['content-type']\n return {\n 'headers': { &quot;Content-Type&quot;: responseContentType },\n 'statusCode': 200,\n 'body': base64.b64encode(responseBody).decode('utf-8'),\n 'isBase64Encoded': True\n }\n except Exception as e:\n print('error message - ', e.__class__.__name__, ' : ', e)\n \n return {\n 'statusCode': 200,\n 'body': 'no file: '+key\n }\n \n else:\n # auth failed\n return {\n 'statusCode': 403,\n 'body': 'request is forbidden'\n }\n</code></pre>\n<p>Lambda Source Code 说明:</p>\n<p>在 Cloudfront 回源时,添加 lambda_auth header,用于 Lambda 认证请求,当认证失败时,返回 403 错误。</p>\n<p>当请求根目录时,返回 index.html</p>\n<p>当 request header 包含 test_version 时,转向到指定目录下的文件。</p>\n<p>将返回的 body 通过 base64 编码,以支持 binary 对象。</p>\n<p>当 request header 包含 redirect=true 时,返回 302 重定向信息。</p>\n<h4><a id=\"3_API_Gateway_163\"></a><strong>3.新建 API Gateway</strong></h4>\n<p>在 API Gateway 中,新建 HTTP API,比如 API Name:lambdaapi</p>\n<p>新建 Lambda integration,选择上一步创建的 Lambda(lambdaapi)</p>\n<p>在 Configure routes 时,Resource path 设置为 “/{proxy+}”</p>\n<p>在 Deploy Stages中,找到 $default stage 的 Invoke URL,如<a href=\"https://xxx.execute-api.xxx.amazonaws.com/\" target=\"_blank\">https://xxx.execute-api.xxx.amazonaws.com</a>,此为 API Gateway 的请求地址。</p>\n<p>测试 API gateway:</p>\n<ul>\n<li>测试 security header</li>\n</ul>\n<p>测试命令:curl <a href=\"https://xxx.execute-api.xxx.amazonaws.com/\" target=\"_blank\">https://xxx.execute-api.xxx.amazonaws.com</a></p>\n<p>返回结果:request is forbidden</p>\n<ul>\n<li>测试访问根路径,传入 lambda_auth header</li>\n</ul>\n<p>测试命令:curl -v -H “lambda_auth:lambdaapi_test” <a href=\"https://xxx.execute-api.xxx.amazonaws.com/\" target=\"_blank\">https://xxx.execute-api.xxx.amazonaws.com</a></p>\n<p>返回结果:statusCode=200</p>\n<ul>\n<li>访问 B 测试页,传入 lambda_auth header和test_version header</li>\n</ul>\n<p>测试命令:curl -H “lambda_auth:lambdaapi_test” -H “test_version:v2” <a href=\"https://xxx.execute-api.xxx.amazonaws.com/test.html\" target=\"_blank\">https://xxx.execute-api.xxx.amazonaws.com/test.html</a></p>\n<p>返回 v2/test.html 的内容</p>\n<ul>\n<li>访问B测试图片,传入 lambda_auth header 和 test_version header</li>\n</ul>\n<p>测试命令:curl -H “lambda_auth:lambdaapi_test” -H “test_version:v2” <a href=\"https://xxx.execute-api.xxx.amazonaws.com/test.\" target=\"_blank\">https://xxx.execute-api.xxx.amazonaws.com/test</a>.png &gt; test.png</p>\n<p>将 response 保存为 test.png 图片。</p>\n<ul>\n<li>测试 redirect,传入 redirect header</li>\n</ul>\n<p>测试命令:curl -v -H “lambda_auth:lambdaapi_test” -H “test_version:v1” -H “redirect:true” <a href=\"https://mgneszib8a.execute-api.xxx.amazonaws.com/test.html\" target=\"_blank\">https://xxx.execute-api.xxx.amazonaws.com/test.html</a></p>\n<p>返回 302 重定向信息</p>\n<h4><a id=\"4_Cloudfront_205\"></a><strong>4.配置 Cloudfront</strong></h4>\n<h5><a id=\"1_Origin_request_policyAmazon_Cloud_Global_207\"></a><strong>1)创建 Origin request policy,Amazon Cloud Global支持该功能</strong></h5>\n<p>在 Cloudfront Policies 中,新建 origin request policy,例如 Name:lambdaapi</p>\n<p>配置如下:</p>\n<p>Headers:选择 Include the following headers,并手工添加 header:test_version和redirect</p>\n<p>Query strings: All</p>\n<p>Cookies:All</p>\n<h5><a id=\"2_Cloudfront_Distribution_219\"></a><strong>2)创建 Cloudfront Distribution</strong></h5>\n<p>在 Cloudfront 中,新建 Distribution,例如 Description:lambdaapi</p>\n<p>配置如下:</p>\n<p>Origin domain:xxx.execute-api.xxx.amazonaws.com,上面创建的 HTTP API 域名</p>\n<p>Protocol:HTTPS only</p>\n<p>Add custom header:</p>\n<p>Header name = lambda_auth,Value = lambdaapi_test</p>\n<p>在 Amazon Cloud Global,支持 Cache policy and origin request policy (recommended),配置下面两个参数:</p>\n<p>Cache policy:CachingDisabled</p>\n<p>Origin request policy:Custom lambdaapi</p>\n<p>或者在 Amazon Cloud China,支持 Legacy cache settings,配置下面 3 个参数:</p>\n<p>Headers:选择 Include the following headers,并手工添加header:test_version和redirect。</p>\n<p>Query strings: All</p>\n<p>Cookies:All</p>\n<p>如果不需要 Cloudfront 缓存内容时,需要设置 Object caching 为Customize,同时将 Minimum TTL、Maximum TTL 和 Default TTL 都设为 0.</p>\n<p>注:需新建 origin 和 behavior,配合 redirect 后 Cloudfront 地址。</p>\n<h4><a id=\"5_Cloudfront_251\"></a><strong>5.测试 Cloudfront</strong></h4>\n<p>1.在 Cloudfront Distributions (Lambdaapi)的 General Details 中,找到 Distribution domain name,例如 cloudfront.net</p>\n<p>2.访问 A 测试页,传入 test_version header</p>\n<p>测试命令:curl -H “test_version:v1” https://xxx.cloudfront.net/test.html</p>\n<p>返回 v1/test.html 的内容</p>\n<p>3.测试 redirect,传入 test_version 和 redirect header</p>\n<p>测试命令:curl -I -H “test_version:v1” -H “redirect:true” https://xxx.cloudfront.net/test.html</p>\n<p>返回 302 重定向的内容</p>\n<h3><a id=\"_267\"></a><strong>结论</strong></h3>\n<p>在这篇文章中,介绍了如何利用 API Gateway 和 Lambda 处理Cloudfront 的内容请求,实现 Lambda@edge 的功能,在实验中,介绍了 Amazon S3、Lambda、API Gateway 和 Cloudfront 的配置方法,实现了 rewrite 和 redirect 的测试场景。</p>\n<h3><a id=\"_271\"></a><strong>参考资料</strong></h3>\n<ul>\n<li><a href=\"https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html\" target=\"_blank\">https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html</a></li>\n<li>https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html</li>\n<li><a href=\"https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html\" target=\"_blank\">https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html</a></li>\n<li><a href=\"https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-dynamo-db.html\" target=\"_blank\">https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-dynamo-db.html</a></li>\n<li><a href=\"https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.SimpleDistribution.html\" target=\"_blank\">https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.SimpleDistribution.html</a></li>\n<li>https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.html</li>\n</ul>\n<h3><a id=\"_280\"></a><strong>本篇作者</strong></h3>\n<p><img src=\"https://dev-media.amazoncloud.cn/e9e49fa460bd48f58ce15ec693268667_image.png\" alt=\"image.png\" /></p>\n<h4><a id=\"_284\"></a><strong>薛召兵</strong></h4>\n<p>Amazon 解决方案架构师,负责帮助客户进行上云架构的设计和咨询。同时致力于 Amazon 容器服务、媒体服务和机器学习服务在国内和全球商业客户的应用和推广,推进企业服务迁移上云进程。有 10 年以上的软件开发、售前技术支持、系统架构设计等经验。</p>\n"}
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭
contact-us