• 关于

    触发器-使用

    的搜索结果

问题

仅当行已更改时,MySQL才会在更新后触发

保持可爱mmm 2020-05-11 10:47:57 1 浏览量 回答数 1

回答

Serverless 工作流本身没有提供定时触发工作流执行的功能,借助于函数计算 (FunctionCompute,简称 FC)的定时触器可以很方便的实现工作流定时调用。本文介绍如何使用 Serverless 工作流提供的定时触发工作流应用,来达到定时执行工作流的目的。 应用框架 定时触发工作流的执行流程如下: FC 定时触发器会定时执行 FC 函数。 FC 函数通过 Serverless 工作流 SDK 调用 StartExecution API 执行 Serverless 工作流。8b0732b23943d746 应用部署 创建定时触发工作流应用 在 Serverless 工作流应用中心 创建定时触发工作流应用。 81ade77a13121123 说明 应用名称:自定义的资源编排服务 ROS 资源栈名称,同一个账号下需保证唯一。 Cron 定时触发工作流的 Cron 表达式,参见 FC 定时触发器,默认为每分钟触发一次。 Input 触发执行工作流的输入,必须为 JSON 格式,默认为空。 部署成功后可看到应用创建的所有资源。de339104fa7aaff8其中包括: RAM 角色:fnf-timer-demo-serviceRole、fnf-timer-demo-flowRole。 FC 资源: 服务 fnf-timer-demo-service、函数 timer、函数 hello、定时触发器 trigger。 Serverless 工作流 资源:工作流 fnf-timer-demo-flow。 验证生效 前往 Serverless 工作流控制台可看到应用创建的工作流 fnf-timer-demo-flow 被定时触发 。17b3faa193bafe86示例工作流使用 任务步骤 调用 FC 函数 hello,定义如下。 version: v1 type: flow steps: - type: task name: hello resourceArn: 'acs:fc:::services/fnf-time-demo-service/functions/hello' 您可以修改该工作流的定义实现自身的业务逻辑。

1934890530796658 2020-03-27 10:52:42 0 浏览量 回答数 0

问题

MySQL触发器将字段更新为id的值?mysql

保持可爱mmm 2020-05-18 09:52:30 5 浏览量 回答数 1

阿里云试用中心,为您提供0门槛上云实践机会!

0元试用32+款产品,最高免费12个月!拨打95187-1,咨询专业上云建议!

回答

ReRDSMSSQL对SQL的支持有哪些需要注意的吗? 如果和本地MS SQL支持不一致,是否应该在一些帮助页面有所说明和罗列 好让选择是否购买和迁移提供依据 ------------------------- ReRDSMSSQL对SQL的支持有哪些需要注意的吗? 只能在用户数据库内建立对象,不可在master、msdb、tempdb、model等系统数据库中建立用户对象 ----- 感觉还是不够直接,那到底临时表和触发器能不能用啊?严格意义上它们也算MASTER和TEMPDB的对象,但又不完全是. 关键是RDS一个月价格太贵,否则先买自己测试了,3楼的你能否测试一下?比如直接一个存储过程内使用临时表?比如建个小表创建个小触发器?

realonedot 2019-12-02 00:09:48 0 浏览量 回答数 0

回答

连续点击会触发浏览器的文本选择行为,要阻止此行为,使用以下 css:span { user-select: none; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;

小旋风柴进 2019-12-02 02:28:28 0 浏览量 回答数 0

回答

连续点击会触发浏览器的文本选择行为,要阻止此行为,使用以下 css:span { user-select: none; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; }

a123456678 2019-12-02 02:04:55 0 浏览量 回答数 0

问题

Spring Quartz 调度器的使用

a123456678 2019-12-01 20:25:24 962 浏览量 回答数 1

回答

详细解答可以参考官方帮助文档 使用 mysqldump 工具的优点是简单易用、容易上手,缺点是停机时间较长,因此它适用于数据量不大,或者允许停机的时间较长的情况。 背景信息 由于 RDS 提供的关系型数据库服务与原生的数据库服务完全兼容,所以对用户来说,将原有数据库迁移到 RDS 实例的过程,与从一个 MySQL 服务器迁移到另外一台 MySQL 服务器的过程基本类似。 前提条件 已对RDS 实例设置白名单,申请外网地址,以及创建数据库和账号。具体可参见快速入门。 已购买云服务器 ECS。 操作步骤 在正式迁移之前,需要先在本地数据库中创建迁移账号,并将要迁移的数据库的读写权限授权给迁移账号。 在本地数据库中创建迁移账号。CREATE USER'username'@'host' IDENTIFIED BY 'password';参数说明: username:要创建的账号 host:指定该账号登录数据库的主机。如果是本地用户可以使用 localhost,如果想让该用户从任意主机登录,可以使用通配符 % password:该账号的登录密码 例:要创建账号为 William,密码为 Changme123 的账号从任意主机登录本地数据库,命令如下: CREATE USER'William'@'%' IDENTIFIED BY 'Changme123'; 在本地数据库中给迁移账号授权。GRANT SELECT ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION; GRANT REPLICATION SLAVE ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION;参数说明: privileges:该账号的操作权限,如 SELECT、INSERT、UPDATE 等。如果要授权该账号所有权限,则使用 ALL databasename:数据库名。如果要授权该账号所有的数据库权限,则使用通配符 * tablename:表名。如果要授权该账号所有的表权限,则使用通配符 * username:要授权的账号名 host:授权登录数据库的主机名。如果是本地用户可以使用 localhost,如果想让该用户从任意主机登录,可以使用通配符 % WITH GRANT OPTION:授权该账号能使用GRANT命令,该参数为可选 例:授权账号 William 对所有数据库和表的所有权限,并可以从任意主机登录本地数据库,命令如下。 GRANT ALL ON*.* TO 'William'@'%'; 使用 mysqldump 的数据导出工具,将本地数据库数据导出为数据文件。 说明 导出期间请勿进行数据更新。本步骤仅仅导出数据,不包括存储过程、触发器及函数。 mysqldump -h localIp -u userName -p --opt --default-character-set=utf8 --hex-blob dbName --skip-triggers > /tmp/dbName.sql参数说明: localIp:本地数据库服务器 IP 地址 userName:本地数据库的迁移账号 dbName:需要迁移的数据库名 /tmp/dbName.sql:备份生成的文件名 使用 mysqldump 导出存储过程、触发器和函数。 说明 若数据库中没有使用存储过程、触发器和函数,可跳过此步骤。在导出存储过程、触发器和函数时,需要将 definer 去掉,以兼容 RDS。 mysqldump -h localIp -u userName -p --opt --default-character-set=utf8 --hex-blob dbName -R | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > /tmp/triggerProcedure.sql参数说明: localIp:本地数据库服务器 IP 地址 userName:本地数据库的迁移账号 dbName:需要迁移的数据库名 /tmp/triggerProcedure.sql:备份生成的文件名 将数据文件和存储过程文件上传到 ECS 上。 本例以文件上传到如下路径为例。/tmp/dbName.sql /tmp/triggerProcedure.sql 登录 ECS,将数据文件和存储过程文件导入到目标 RDS 中。mysql -h intranet4example.mysql.rds.aliyuncs.com –u userName -p dbName < /tmp/dbName.sql mysql -h intranet4example.mysql.rds.aliyuncs.com -u userName -p dbName < /tmp/triggerProcedure.sql参数说明: intranet4example.mysql.rds.aliyuncs.com:RDS 实例连接地址,本例以内网地址为例 userName:RDS 数据库的迁移账号 dbName:需要导入的数据库名 /tmp/dbName.sql:要导入的数据文件名 /tmp/triggerProcedure.sql:要导入的存储过程文件名

2019-12-01 22:57:10 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 使用 mysqldump 工具的优点是简单易用、容易上手,缺点是停机时间较长,因此它适用于数据量不大,或者允许停机的时间较长的情况。 背景信息 由于 RDS 提供的关系型数据库服务与原生的数据库服务完全兼容,所以对用户来说,将原有数据库迁移到 RDS 实例的过程,与从一个 MySQL 服务器迁移到另外一台 MySQL 服务器的过程基本类似。 前提条件 已对RDS 实例设置白名单,申请外网地址,以及创建数据库和账号。具体可参见快速入门。 已购买云服务器 ECS。 操作步骤 在正式迁移之前,需要先在本地数据库中创建迁移账号,并将要迁移的数据库的读写权限授权给迁移账号。 在本地数据库中创建迁移账号。CREATE USER'username'@'host' IDENTIFIED BY 'password';参数说明: username:要创建的账号 host:指定该账号登录数据库的主机。如果是本地用户可以使用 localhost,如果想让该用户从任意主机登录,可以使用通配符 % password:该账号的登录密码 例:要创建账号为 William,密码为 Changme123 的账号从任意主机登录本地数据库,命令如下: CREATE USER'William'@'%' IDENTIFIED BY 'Changme123'; 在本地数据库中给迁移账号授权。GRANT SELECT ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION; GRANT REPLICATION SLAVE ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION;参数说明: privileges:该账号的操作权限,如 SELECT、INSERT、UPDATE 等。如果要授权该账号所有权限,则使用 ALL databasename:数据库名。如果要授权该账号所有的数据库权限,则使用通配符 * tablename:表名。如果要授权该账号所有的表权限,则使用通配符 * username:要授权的账号名 host:授权登录数据库的主机名。如果是本地用户可以使用 localhost,如果想让该用户从任意主机登录,可以使用通配符 % WITH GRANT OPTION:授权该账号能使用GRANT命令,该参数为可选 例:授权账号 William 对所有数据库和表的所有权限,并可以从任意主机登录本地数据库,命令如下。 GRANT ALL ON*.* TO 'William'@'%'; 使用 mysqldump 的数据导出工具,将本地数据库数据导出为数据文件。 说明 导出期间请勿进行数据更新。本步骤仅仅导出数据,不包括存储过程、触发器及函数。 mysqldump -h localIp -u userName -p --opt --default-character-set=utf8 --hex-blob dbName --skip-triggers > /tmp/dbName.sql参数说明: localIp:本地数据库服务器 IP 地址 userName:本地数据库的迁移账号 dbName:需要迁移的数据库名 /tmp/dbName.sql:备份生成的文件名 使用 mysqldump 导出存储过程、触发器和函数。 说明 若数据库中没有使用存储过程、触发器和函数,可跳过此步骤。在导出存储过程、触发器和函数时,需要将 definer 去掉,以兼容 RDS。 mysqldump -h localIp -u userName -p --opt --default-character-set=utf8 --hex-blob dbName -R | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > /tmp/triggerProcedure.sql参数说明: localIp:本地数据库服务器 IP 地址 userName:本地数据库的迁移账号 dbName:需要迁移的数据库名 /tmp/triggerProcedure.sql:备份生成的文件名 将数据文件和存储过程文件上传到 ECS 上。 本例以文件上传到如下路径为例。/tmp/dbName.sql /tmp/triggerProcedure.sql 登录 ECS,将数据文件和存储过程文件导入到目标 RDS 中。mysql -h intranet4example.mysql.rds.aliyuncs.com –u userName -p dbName < /tmp/dbName.sql mysql -h intranet4example.mysql.rds.aliyuncs.com -u userName -p dbName < /tmp/triggerProcedure.sql参数说明: intranet4example.mysql.rds.aliyuncs.com:RDS 实例连接地址,本例以内网地址为例 userName:RDS 数据库的迁移账号 dbName:需要导入的数据库名 /tmp/dbName.sql:要导入的数据文件名 /tmp/triggerProcedure.sql:要导入的存储过程文件名

2019-12-01 22:57:10 0 浏览量 回答数 0

回答

vmstat 1这个命令执行截图发下,慢的时候 。 ------------------------- 重启,主要看下面几个CPU使用量内存是否用光IO读写值IO wait值以过去几年的经验来看能PING通但是系统卡死100%都是内存用光了。不要说没有访问量用不了多少内存,能导致内存用光除了访问量还有很多别的原因。 ------------------------- TO 8楼,webkaka和别的测速网站不会触发或者调用CSS JS之类的文件,这些文件也不会导致负载升高。 ------------------------- 前些天遇到一个用WDCP的在访问量正常的情况下使用NGINX APACHE模式飙升到几十个APACHE进程后导致内存用光,具体原因未知,换成NGINX后正常。仅供参考。 ------------------------- 访问慢有很多方面系统慢网络慢浏览器加载慢方向不能搞错。更换主题 不会影响在webkaka里的测试速度,也不会影响系统负载。 ------------------------- 很多需要的信息你都不能及时提供,别的东西现在不好说,我曾经在64M内存的VPS中使用LNMP环境中跑过几个月的wordpress,几百条文章。wordpress慢是众所周知的,但是你的情况现在确切的说,不是慢,是异常。

云代维 2019-12-02 01:38:43 0 浏览量 回答数 0

回答

这是您要寻找的: LAST_INSERT_ID() 为了回应OP的评论,我创建了以下基准测试: CREATE TABLE Foo ( FooId INT AUTO_INCREMENT PRIMARY KEY ); CREATE TABLE Bar ( BarId INT AUTO_INCREMENT PRIMARY KEY ); INSERT INTO Bar () VALUES (); INSERT INTO Bar () VALUES (); INSERT INTO Bar () VALUES (); INSERT INTO Bar () VALUES (); INSERT INTO Bar () VALUES (); CREATE TRIGGER FooTrigger AFTER INSERT ON Foo FOR EACH ROW BEGIN INSERT INTO Bar () VALUES (); END; INSERT INTO Foo () VALUES (); SELECT LAST_INSERT_ID(); 返回: +------------------+ | LAST_INSERT_ID() | +------------------+ | 1 | +------------------+ 因此,它使用LAST_INSERT_ID()原始表的,而不INSERT使用触发器内部的表。 编辑:经过所有这些时间,我意识到SELECT LAST_INSERT_ID()答案中显示的结果是错误的,尽管最后的结论是正确的。我已将结果更新为正确的值。来源:stack overflow

保持可爱mmm 2020-05-17 12:31:40 0 浏览量 回答数 0

回答

使本文介绍使用 Jenkins 构建 SAE 应用的持续集成。 前提条件 在开始持续集成之前,需要完成下述的准备工作。 获取阿里云的 Access Key ID 和 Access Key Secret。 使用已经开通了 SAE 服务的主账号登录阿里云官网。 进入 Access Key 控制台,创建 Access Key ID 和 Access Key Secret。EDAS使用 Jenkins 创建持续集成01 在使用 Jenkins 自动部署应用之前,需要先在 SAE 控制台中创建一个可以部署的应用。 登录 SAE 控制台。 参考应用部署概述,部署应用。 在左侧导航栏中单击应用管理。找到您在上一步中创建的应用并单击进入详情页面,获取应用 ID 的字段内容。在SAE控制平台获取应用ID 使用 GitLab 托管您的代码。您可以自行搭建 Gitlab 或者使用阿里云 Code。 本文使用通过自行搭建的 GitLab 做演示,关于 Gitlab 的更多信息请参考 GitLab。 了解并使用 Jenkins。关于 Jenkins 的更多详细信息请参考 Jenkins 官网。 背景信息 使用 Jenkins 可以构建 SAE 应用的持续集成方案。该方案涉及下面的计算机语言或开发工具,阅读本文需要对下述的语言或工具有一定的理解。 工具 说明 Maven Maven 是一个项目管理和构建的自动化工具。 Jenkins Jenkins是一个可扩展的持续集成引擎。 GitLab GitLab是一个利用 Ruby on Rails 开发的开源应用程序,实现一个自托管的 Git 项目仓库,可通过 Web 界面进行访问公开的或者私人项目。 它拥有与 GitHub 类似的功能,能够浏览源代码,管理缺陷和注释。 配置项目 参考通过 toolkit-maven-plugin 插件自动化部署应用修改项目配置,添加 toolkit-maven-plugin 及部署信息。您在修改完项目配置后,建议在本地使用 Maven 构建验证配置是否正确。 安装和配置 Jenkins 进入 Jenkins 官网下载安装 Jenkins。 在 Jenkins 控制台的菜单栏中选择系统管理 > 插件管理,安装 Git 和 GitLab 插件。 安装 GIT Client Plugin 和 GIT Plugin 插件可以帮助 Jenkins 拉取 Git 仓库中的代码。 安装 Gitlab Hook Plugin 插件可以帮助 Jenkins 在收到 Gitlab 发来的 Hook 后触发一次构建。 安装和配置 Jenkins 安装 Maven 构建工具,请参见 Maven 官网。 在 Jenkins 控制台的菜单栏中选择系统管理 > 全局工具配置,选择 Maven 版本名称并配置路径。 Jenkins 控制台设置Maven 在 Jenkins 服务器上生成 SSH RSA 密钥对,并将公匙导入 GitLab,实现 Jenkins 拉取 GitLab 代码时自动认证。 参考 GitLab 文档,在 Jenkins 服务器运行 Jenkins 软件的用户下,生成 SSH RSA 密钥对。 EDAS在 Jenkins 服务器运行 Jenkins 软件的用户下,生成 SSH RSA 密钥对 进入 GitLab 首页,在菜单栏选择Settings > Deploy Keys ,并单击 new deploy key 添加 key,导入在Jenkins服务器上创建的SSH RSA公匙。 EDAS使用Jenkins在gitlab导公钥1EDAS使用Jenkins在gitlab导公钥2 创建 Jenkins 任务。 在 Jenkins 首页左侧导航栏中单击新建,创建 Jenkins 任务,并选择构建一个自由风格的软件项目。 EDAS使用Jenkins集成之创建项目 在 源码管理 页面中选择 Git,并设置相关参数。 Repository URL:您的项目的 Git 协议地址。 Credentials:安全凭证,选择无即可(前提是运行 Jenkins 软件的用户的 SSH RSA 公匙已添加到该 Git 项目所在的 GitLab 中,否则这里会报错)。 EDAS使用Jenkins集成之源码管理 单击构建触发器页签,勾选轮询 SCM。 单击构建环境页签,勾选 Add timestamps to the Console Output(为控制台输出的信息添加时间戳)。 单击构建页签,然后单击增加构建步骤。 在调用顶层 Maven 目标区域设置 Maven 版本和目标。如果您想部署多模块工程,请参见创建多模块工程的 Jenkins 任务。 Maven Version:单击该选项后面的下拉框,选择在全局工具配置里配置的 Maven 版本名称。 Goals:填入 clean package toolkit:deploy (如有其它参数,请根据实际情况填入) EDAS使用Jekins集成之调用顶层 Maven 目标 配置 Gitlab 的 Web Hook,实现自动构建 右键单击 GitLab 工程,然后选择 Setting > Web Hooks。 在 Web Hooks 页面的在 URL 文本框中输入http://jenkins服务器地址:jenkins服务器监听端口/git/notifyCommit?url=本项目的git协议地址 例如:http://123.57.57.164:8080/git/notifyCommit?url=git@code.aliyun.com:tdy218/hello-edas.git 配置 Gitlab 的 Web Hook,实现自动构建 图中表示的 Jenkins 服务器地址为您的 Jenkins 服务器的 Web 访问地址如 http://123.57.57.164:8080。 配置完成后,单击 Test Hook,进行测试。 配置 Gitlab 的 Web Hook结果 配置正确后,提交变更到 GitLab 如果上述步骤配置正确,这次提交会触发一次 GitLab Hook。 Jenkins 在接受到这个 Hook 后会构建您的 Maven 项目,并在构建结束时调用 SAE POP API 脚本触发部署。 提交部署成功输出的日志信息(Build Number > 控制台输出)。 15:58:51 [INFO] Deploy application successfully! 15:58:51 [INFO] ------------------------------------------------------------------------ 15:58:51 [INFO] BUILD SUCCESS 15:58:51 [INFO] ------------------------------------------------------------------------ 15:58:51 [INFO] Total time: 24.330 s 15:58:51 [INFO] Finished at: 2018-12-25T15:58:51+08:00 15:58:51 [INFO] Final Memory: 23M/443M 15:58:51 [INFO] ------------------------------------------------------------------------ 15:58:51 Finished: SUCCESS 如果部署失败,可以登录 SAE 控制台 ,在左侧导航栏中单击应用管理 > 应用列表 ,在应用列表页面单击具体应用名称,进入应用详情页面。在左侧导航栏单击变更记录来查看此次部署任务的执行过程。 创建多模块工程的 Jenkins 任务 创建多模块工程的 Jenkins 任务和安装和配置 Jenkins第 5 步基本相同,只需要调整下调用顶层 Maven 目标。如果工程为多模块工程,想在 Jenkins 中部署子模块的话,那么需要在父模块中调用 mvn clean install 命令,然后在子模块中调用 mvn clean package toolkit:deploy 命令。以 Demo 工程为例,工程结构如下: sh-3.2# tree -L 1 carshop carshop ├── detail ├── itemcenter ├── itemcenter-api └── pom.xml 其中,detail、itemcenter、itemcenter-api 为子模块,现在想部署 itemcenter 模块的话,那么需要在父工程中设置一个 clean install 构建目标,然后在 itemcenter 模块中设置 clean package toolkit:deploy 构建目标。 创建多模块工程的 Jenkins 任务

1934890530796658 2020-03-27 13:10:36 0 浏览量 回答数 0

回答

Relbs定位精度550米,我要GPS啊。。。。。 上次反应的让用户自己决定要哪个provider的数据也不知道怎么样了 ------------------------- Relbs定位精度550米,我要GPS啊。。。。。 钉钉的JS-API我就测试了几个,感觉挺简单的呀 ------------------------- Relbs定位精度550米,我要GPS啊。。。。。 要想正常使用jsapi就必正常签名,只要能触发dd.ready就表示签名不会有问题,出问题的话先看是不是请求激活接口了,再看参数和返回值是不是正常。 有些问题不是签名的问题,而是api的设计人员没考虑象我这样的对纯gps定位有需求的人群。 ------------------------- Relbs定位精度550米,我要GPS啊。。。。。 今天在路边获取到的WiFi定位精度100米,客户要求50米,何解,目前钉钉api并不能满足100%达标 ------------------------- Relbs定位精度550米,我要GPS啊。。。。。 油田巡井业务很多都在非常偏的荒郊野地里,油井全部使用gps坐标,巡井人必须使用gps啊,精度要求很高的。钉钉不是做不到啊,所谓的期望值和目前的坐标返回逻辑对于需要精确定位的完全起的负作用 ------------------------- 回 10楼君信的帖子 十分感谢 ------------------------- 回 14楼识器的帖子 文档里没有写参数名是什么,可否告知下参数名?

浮云若海 2019-12-02 01:39:10 0 浏览量 回答数 0

回答

这是我的写法: CREATE TRIGGER [dbo].[TriggerClosureAction] ON [dbo].[Actions] AFTER UPDATE,DELETE AS UPDATE t SET [Status] = 0 FROM dbo.Tickets As t -- update only records effected from the current operation INNER JOIN DELETED As d ON t.TicketNumber = d.IdTicket -- No records left for that ticket number with status 1 in the actions table WHERE NOT EXISTS ( SELECT 1 FROM Actions As A WHERE A.IdTicket = t.TicketNumber AND A.[Status] <> 0 ) 更新使用连接到票表deleted表,以确保只有相关的记录被更新-因为deleted表包含了所有来自受影响的记录delete或update触发触发器,那里没有留下记录,如果该语句actions表,其中status不是0-由于这是一个触发器,因此actions表中的数据已经反映了触发该触发器的语句的结果。

祖安文状元 2020-01-05 18:02:55 0 浏览量 回答数 0

问题

Swarm 集群&nbsp;&nbsp;DevOps&nbsp;&nbsp;基于 Jenkins 的持续交付

青蛙跳 2019-12-01 21:36:21 643 浏览量 回答数 0

回答

我建议使用INSERT...ON DUPLICATE KEY UPDATE。 如果使用INSERT IGNORE,那么如果该行导致重复键,则实际上不会插入该行。但是该语句不会产生错误。而是生成警告。这些情况包括: 在具有PRIMARY KEY或UNIQUE约束的列中插入重复的键。 将NULL插入具有NOT NULL约束的列中。 在分区表中插入一行,但是您插入的值不会映射到分区。 如果使用REPLACE,MySQL实际上会在内部执行,DELETE然后执行INSERT内部操作,这会产生一些意外的副作用: 分配了一个新的自动增量ID。 带有外键的相关行可能会被删除(如果您使用级联外键),否则可能会阻止REPLACE。 触发的触发器DELETE不需要执行。 副作用也传播到副本。 修正:既REPLACE和INSERT...ON DUPLICATE KEY UPDATE是非标准的,私有的发明具体到MySQL。ANSI SQL 2003定义了MERGE可以满足相同需求(甚至更多)的MERGE语句,但是MySQL不支持该语句。 一位用户尝试编辑此帖子(主持人拒绝了该编辑)。修改尝试添加一个声明,该声明INSERT...ON DUPLICATE KEY UPDATE导致分配了新的自动递增ID。确实会生成新的id ,但是更改后的行中不会使用它。 请参见下面的演示,该演示已通过Percona Server 5.5.28测试。配置变量innodb_autoinc_lock_mode=1(默认): mysql> create table foo (id serial primary key, u int, unique key (u)); mysql> insert into foo (u) values (10); mysql> select * from foo; +----+------+ | id | u | +----+------+ | 1 | 10 | +----+------+ mysql> show create table foo\G CREATE TABLE foo ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, u int(11) DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY u (u) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 mysql> insert into foo (u) values (10) on duplicate key update u = 20; mysql> select * from foo; +----+------+ | id | u | +----+------+ | 1 | 20 | +----+------+ mysql> show create table foo\G CREATE TABLE foo ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, u int(11) DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY u (u) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 上面的示例表明IODKU语句检测到重复项,并调用更新以更改的值u。请注意,AUTO_INCREMENT=3表示已生成ID,但未在行中使用。 而REPLACE确实会删除原始行并插入新行,从而生成并存储新的自动增量ID: mysql> select * from foo; +----+------+ | id | u | +----+------+ | 1 | 20 | +----+------+ mysql> replace into foo (u) values (20); mysql> select * from foo; +----+------+ | id | u | +----+------+ | 3 | 20 | +----+------+

保持可爱mmm 2020-05-08 10:46:51 0 浏览量 回答数 0

回答

Re运行的程序每隔一段时间被自动杀掉 你说程序被kill掉,是通过什么信息判断出来的呢? 系统的log吗? ------------------------- 回2楼lgwinner的帖子 那你需要先定位到退出的原因。 程序在后台运行后,跟ssh的退出已经没有关系。 如果你的程序过一段时间后就自动退出了,可能有两种原因: 1)你的程序有bug,运行过程中触发bug,导致退出; 2)你的程序使用了大量的内存,导致系统oom-killer把你的程序给杀掉了,oom是out-of-memory的缩写; 如果是第二种情况,在系统的/var/log/syslog里面会有记录,这种情况通过查看/var/log/syslog的内容,检索是否有你的应用程序的信息可以判断; 第一种情况,需要你自己使用python调试器,调试程序是什么时候因为什么原因退出的。

云语科技 2019-12-02 02:07:04 0 浏览量 回答数 0

问题

利用MySQLdump备份数据

cvvn 2019-12-01 21:25:47 6493 浏览量 回答数 0

回答

本文旨在介绍如何将基于 WSGI web 框架构建的工程部署到函数计算 python runtime 的具体操作过程,在介绍操作过程之前,先了解几个概念。 相关概念导读 函数计算 HTTP 触发器 HTTP 触发器是众多函数计算触发器中的一种,通过发送 HTTP 请求触发函数执行。主要适用于快速构建 Web 服务等场景。HTTP 触发器支持 HEAD、POST、PUT、GET 和 DELETE 方式触发函数。具体详情可以参考 HTTP 触发器 什么是WSGI WSGI的全称是 Web Server Gateway Interface,简单翻译就是 Web 服务器网关接口。具体来说,WSGI 是一个规范,定义了 Web 服务器如何与 Python 应用程序进行交互,使得使用 Python 写的 Web 应用程序可以和 Web 服务器对接起来。最新官方版本是在 Python 的 PEP-3333 定义的。 WSGI 如何工作 在 WSGI 中定义了两个角色,Web 服务器端称为 server 或者 gateway,应用程序端称为 application 或者 framework(因为 WSGI 的应用程序端的规范一般都是由具体的框架来实现的,下面统一使用 server 和 application 这两个术语,WSGI 相当于是 Web 服务器和 Python 应用程序之间的桥梁。server 端会先收到用户的请求,然后会根据规范的要求调用 application 端,然后 server 会将调用 application 返回的结果封装成 HTTP 响应后再发送给客户端,如下图所示: wsgi-fc 如果想了解更多关于WSGI的内容,请查阅 PEP-3333 函数计算遇见 WSGI FC python runtime 是 server,用户的函数是 application,applicaiton 可以完全自己实现,也可以基于 wsgi 的 web 框架上进行函数开发,具体可以参考 HTTP 触发器 Python-Runtime , 本文主要讲解如何运用 python wsgi 的 web 框架开发的工程部署到函数计算环境中。 Frameworks that run on WSGI 目前有很不少 Frameworks 是基于 WSGI 协议的,比如 Flask,Django 等,具体可以参考 Frameworks that run on WSGI, 本文讲解两个框架的的工程如何部署在函数计算中: Flask Django 具体详情参考: fc-python-web 部署 准备工作 免费开通 函数计算 准备域名(国内的需要备案过), 并将域名 CNAME 解析到对应的 FC EndPoint 比如将自己的域名 flask.mydomain.cn 解析到 123456.cn-hangzhou.fc.aliyuncs.com, 对应的域名、accountId 和 region 修改成自己的 安装 Fun 工具 安装版本为8.x 最新版或者10.x 、12.x nodejs 安装 funcraf $ npm install @alicloud/fun -g 安装完成后, 执行 fun config,按照提示完成 fun 的配置,参考:getting_started Clone 工程,在工程目录上,命令行输入 fun deploy 执行 $ git clone https://github.com/awesome-fc/fc-python-web.git $ cd fc-python-web 先将 template 中的 CustomDomain 修改成自己的 $ fun deploy

1934890530796658 2020-03-27 17:36:22 0 浏览量 回答数 0

回答

作为一种解决方法,您可以使用时间戳(旧的和新的)来检查,如果该行没有更改,则不会更新该时间戳。(可能是造成混乱的根源?因为那也被称为“更新时”,但是在没有任何变化的情况下不会执行)一秒钟之内的变化将不会执行触发器的那部分,但是在某些情况下可能会很好(例如,当您的应用程序仍然拒绝快速更改时。) 例如,而不是 IF NEW.a <> OLD.a or NEW.b <> OLD.b /* etc, all the way to NEW.z <> OLD.z */ THEN INSERT INTO bar (a, b) VALUES(NEW.a, NEW.b) ; END IF 你可以用 IF NEW.ts <> OLD.ts THEN INSERT INTO bar (a, b) VALUES(NEW.a, NEW.b) ; END IF 这样,您就不必在每次更新方案时都更改触发器(问题中提到的问题)。 编辑:添加了完整的示例 create table foo (a INT, b INT, ts TIMESTAMP); create table bar (a INT, b INT); INSERT INTO foo (a,b) VALUES(1,1); INSERT INTO foo (a,b) VALUES(2,2); INSERT INTO foo (a,b) VALUES(3,3); DELIMITER /// CREATE TRIGGER ins_sum AFTER UPDATE ON foo FOR EACH ROW BEGIN IF NEW.ts <> OLD.ts THEN INSERT INTO bar (a, b) VALUES(NEW.a, NEW.b); END IF; END; /// DELIMITER ; select * from foo; +------+------+---------------------+ | a | b | ts | +------+------+---------------------+ | 1 | 1 | 2011-06-14 09:29:46 | | 2 | 2 | 2011-06-14 09:29:46 | | 3 | 3 | 2011-06-14 09:29:46 | +------+------+---------------------+ 3 rows in set (0.00 sec) -- UPDATE without change UPDATE foo SET b = 3 WHERE a = 3; Query OK, 0 rows affected (0.00 sec) Rows matched: 1 Changed: 0 Warnings: 0 -- the timestamo didnt change select * from foo WHERE a = 3; +------+------+---------------------+ | a | b | ts | +------+------+---------------------+ | 3 | 3 | 2011-06-14 09:29:46 | +------+------+---------------------+ 1 rows in set (0.00 sec) -- the trigger didn't run select * from bar; Empty set (0.00 sec) -- UPDATE with change UPDATE foo SET b = 4 WHERE a=3; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 -- the timestamp changed select * from foo; +------+------+---------------------+ | a | b | ts | +------+------+---------------------+ | 1 | 1 | 2011-06-14 09:29:46 | | 2 | 2 | 2011-06-14 09:29:46 | | 3 | 4 | 2011-06-14 09:34:59 | +------+------+---------------------+ 3 rows in set (0.00 sec) -- and the trigger ran select * from bar; +------+------+---------------------+ | a | b | ts | +------+------+---------------------+ | 3 | 4 | 2011-06-14 09:34:59 | +------+------+---------------------+ 1 row in set (0.00 sec) 由于mysql在处理时间戳方面的行为,因此可以正常工作。仅当更新中发生更改时,时间戳才会更新。 文档在这里:https : //dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html来源:stack overflow

保持可爱mmm 2020-05-11 10:48:22 0 浏览量 回答数 0

回答

使用mysqldump工具的优点是简单易用、容易上手,缺点是停机时间较长,因此它适用于数据量不大,或者允许停机的时间较长的情况。 背景信息 由于RDS提供的关系型数据库服务与原生的数据库服务完全兼容,所以对用户来说,将原有数据库迁移到RDS实例的过程,与从一台MySQL服务器迁移到另外一台MySQL服务器的过程基本类似。 注意事项 迁移后的表不区分大小写,统一变为小写。 前提条件 已对RDS实例设置白名单,申请外网地址,以及创建数据库和账号。具体可参见快速入门。 已购买云服务器 ECS。 操作步骤 在正式迁移之前,需要先在本地数据库中创建迁移账号,并将要迁移的数据库的读写权限授权给迁移账号。 在本地数据库中创建迁移账号。 CREATE USER'username'@'host' IDENTIFIED BY 'password'; 参数说明: username:要创建的账号 host:指定该账号登录数据库的主机。如果是本地用户可以使用 localhost,如果想让该用户从任意主机登录,可以使用通配符 % password:该账号的登录密码 例:要创建账号为 William,密码为 Changme123 的账号从任意主机登录本地数据库,命令如下: CREATE USER'William'@'%' IDENTIFIED BY 'Changme123'; 在本地数据库中给迁移账号授权。 GRANT SELECT ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION; GRANT REPLICATION SLAVE ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION; 参数说明: privileges:该账号的操作权限,如 SELECT、INSERT、UPDATE 等。如果要授权该账号所有权限,则使用 ALL databasename:数据库名。如果要授权该账号所有的数据库权限,则使用通配符 * tablename:表名。如果要授权该账号所有的表权限,则使用通配符 * username:要授权的账号名 host:授权登录数据库的主机名。如果是本地用户可以使用 localhost,如果想让该用户从任意主机登录,可以使用通配符 % WITH GRANT OPTION:授权该账号能使用GRANT命令,该参数为可选 例:授权账号William对所有数据库和表的所有权限,并可以从任意主机登录本地数据库,命令如下。 GRANT ALL ON*.* TO 'William'@'%'; 使用 mysqldump 的数据导出工具,将本地数据库数据导出为数据文件。 说明 导出期间请勿进行数据更新。本步骤仅仅导出数据,不包括存储过程、触发器及函数。 mysqldump -h localIp -u userName -p --opt --default-character-set=utf8 --hex-blob dbName --skip-triggers --skip-lock-tables > /tmp/dbName.sql 参数说明: localIp:本地数据库服务器 IP 地址 userName:本地数据库的迁移账号 dbName:需要迁移的数据库名 /tmp/dbName.sql:备份生成的文件名 使用 mysqldump 导出存储过程、触发器和函数。 说明 若数据库中没有使用存储过程、触发器和函数,可跳过此步骤。在导出存储过程、触发器和函数时,需要将 definer 去掉,以兼容 RDS。 mysqldump -h localIp -u userName -p --opt --default-character-set=utf8 --hex-blob dbName -R | sed -e 's/DEFINER[ ]=[ ][^*]**/*/' > /tmp/triggerProcedure.sql 参数说明: localIp:本地数据库服务器 IP 地址 userName:本地数据库的迁移账号 dbName:需要迁移的数据库名 /tmp/triggerProcedure.sql:备份生成的文件名 将数据文件和存储过程文件上传到 ECS 上。 本例以文件上传到如下路径为例。 /tmp/dbName.sql /tmp/triggerProcedure.sql 登录 ECS,将数据文件和存储过程文件导入到目标 RDS 中。 mysql -h intranet4example.mysql.rds.aliyuncs.com –u userName -p dbName < /tmp/dbName.sql mysql -h intranet4example.mysql.rds.aliyuncs.com -u userName -p dbName < /tmp/triggerProcedure.sql 参数说明: intranet4example.mysql.rds.aliyuncs.com:RDS实例连接地址,本例以内网地址为例 userName:RDS数据库的迁移账号 dbName:需要导入的数据库名 /tmp/dbName.sql:要导入的数据文件名 /tmp/triggerProcedure.sql:要导入的存储过程文件名 常见问题 Q:mysqldump迁移复杂,有简单的方法吗? A:您可以使用DTS从自建MySQL迁移至RDS for MySQL。

游客yl2rjx5yxwcam 2020-03-08 16:35:05 0 浏览量 回答数 0

问题

Swarm 集群&nbsp;&nbsp;DevOps&nbsp;&nbsp;基于容器 HUB 的持续交付

青蛙跳 2019-12-01 21:36:20 488 浏览量 回答数 0

回答

对于每一个请求,函数计算服务会根据请求头部的 Authorization 字段来校验是否合法(设置了 HTTP 触发器的允许匿名访问的函数除外)。客户端须使用与函数计算服务端一致的签名算法才能通过验证,对于未包含签名字段或者签名错误的请求,函数计算服务将会返回 HTTP 403 错误。 本文对函数计算的签名校验算法进行介绍。 签名算法 signature = base64(hmac-sha256(HTTP_METHOD + "\n" + CONTENT-MD5 + "\n" + CONTENT-TYPE + "\n" + DATE + "\n" + CanonicalizedFCHeaders + CanonicalizedResource)) // Authorization字段介绍 Authorization = "FC " + accessKeyID + ":" + signature HTTP_METHOD 表示大写的 HTTP Method (如:PUT, GET, POST, DELETE) CONTENT-MD5 表示请求内容数据的 MD5 值。如果请求的 Header 中没有传 Content-MD5,则此处填入空串 CONTENT-TYPE 表示请求内容的类型 DATE 表示此次操作的时间,不能为空,目前只支持 GMT 格式 注意:客户端需要保证生成的时间与函数计算服务端的时间相差不超过15分钟,否则函数服务将拒绝此请求 CanonicalizedFCHeaders 表示所有以 x-fc- 为前缀的 HTTP 头组成的字符串,生成方式见下文 CanonicalizedResource 表示请求的 URL 的 Path ,一般来说是先对收到的 Path decode,再去掉请求的 Path 里的 Params 内容。 Path 的结构为:$api-version/api-path api-version:API 版本,当前版本为 2016-08-15。 api-path:访问各个接口的路径,例如创建 service 为 /services,其他 path 请参考 API 定义。 需要认证的 HTTP 触发器的CanonicalizedResource 与其他请求的CanonicalizedResource 不同,下面对两种情况分别进行介绍。 普通请求的 CanonicalizedResource (普通请求为除了需要访问带认证的 HTTP 触发器的请求外的所有请求): 首先对收到的 Path 进行 url 解码,普通请求的 CanonicalizedResource 会只取到?前面的内容,即舍弃传入的各个Params 需要认证的 HTTP 触发器的CanonicalizedResource :如果有 Params ,则以回车符 \n 分隔各个参数,Params 中的各个参数 key - value 对按照字母序进行排序(如果 Params 里的 key 对应多个 value ,即对 key - value 整体进行排序)。如果没有 Params,最后也以 \n 结束。例如 // 需要认证的 HTTP 触发器的 url 的真实 path /2016-08-15/proxy/service-name/func-name/path-with-%20-space/action?x=1&a=2&x=3&with%20space=foo%20bar // url decode 后的结果 /2016-08-15/proxy/service-name/func-name/path-with- -space/action?x=1&a=2&x=3&with space=foo bar // 需要认证的 HTTP 触发器的 CanonicalizedResource /2016-08-15/proxy/service-name/func-name/path-with- -space/action\na=2\nwith space=foo bar\nx=1\nx=3 // 普通请求的 url 的真实 path /2016-08-15/service-name/func-name/path-with-%20-space/action?x=1&a=2&x=3&with%20space=foo%20bar // url decode 后的结果 /2016-08-15/service-name/func-name/path-with- -space/action?x=1&a=2&x=3&with space=foo bar // 普通请求的 CanonicalizedResource /2016-08-15/service-name/func-name/path-with- -space/action hmac-sha256需要以用户的 AccessKeySecret 为 Key 伪代码如下: // 构造字符串的过程 function composeStringToSign(method, path, headers, queries) { var contentMD5 = headers['content-md5'] || ''; var contentType = headers['content-type'] || ''; var date = headers['date']; var signHeaders = buildCanonicalHeaders(headers, 'x-fc-'); var u = url.parse(path); var pathUnescaped = decodeURIComponent(u.pathname); var str = ${method}\n${contentMD5}\n${contentType}\n${date}\n${signHeaders}${pathUnescaped}; if (queries) { var params = []; Object.keys(queries).forEach(function (key) { var values = queries[key]; var type = typeof values; if (type === 'string') { params.push(${key}=${values}); return; } if (type === 'object' && values instanceof Array) { queries[key].forEach(function (value) { params.push(${key}=${value}); }); } }); params.sort(); str += '\n' + params.join('\n'); } return str; } // 使用 hmac-sha256 和 base64 计算签名的过程,其中 source 参数为构造出的字符串 function signString(source, secret) { const buff = crypto.createHmac('sha256', secret) .update(source, 'utf8') .digest(); return new Buffer(buff, 'binary').toString('base64'); } CanonicalizedFCHeaders 生成步骤如下: 找出请求头中所有以 x-fc- 开头的字段(不区分大小写) 对于符合前缀的字段,先将字段名转换成小写 对于每一个字段,生成一个子串 ${key}:${value}\n , ${key} 是 HTTP 头的名称(转换成小写) ${value} 是 HTTP 头的值 例如:X-Fc-Invocation-Type:Sync 变成 x-fc-invocation-type:Sync\n 然后将这些字段按字段名从小到大排序 将上述生成的子串连接成一个整串 伪代码如下: // javascript // prefix = 'x-fc-' function buildCanonicalHeaders(headers, prefix) { var list = []; var keys = Object.keys(headers); var fcHeaders = {}; for (var i = 0; i < keys.length; i++) { var key = keys[i]; var lowerKey = key.toLowerCase().trim(); if (lowerKey.startsWith(prefix)) { list.push(lowerKey); fcHeaders[lowerKey] = headers[key]; } } list.sort(); var canonical = ''; for (var _i = 0; _i < list.length; _i++) { var _key = list[_i]; canonical += ${_key}:${fcHeaders[_key]}\n; } return canonical; } Authorization 字段 Authorization 可由上文计算得出的 signature 构造出来,构造方法如下: Authorization = "FC " + accessKeyID + ":" + signature 请求示例 请求: GET /2016-08-15/services?limit=100&nextToken=&prefix=&startKey= HTTP/1.1 Host: 1237050315505682.fc.cn-shanghai.aliyuncs.com User-Agent: go-sdk-0.1 Accept: application/json Authorization: FC LTAIUyt0Yeq1rgqo:GBmoz6OwC7bobTlD1jboBZ9PkaZ1e4cKsQ+5/dlLTns= Date: Mon, 08 May 2017 03:08:31 GMT X-User-Agent: go-resty v0.11 - https://github.com/go-resty/resty Accept-Encoding: gzip 响应: HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 X-Fc-Request-Id: ab7c7602-0922-f04f-b4ee-923cd7df7fb0 Date: Mon, 08 May 2017 03:08:31 GMT Transfer-Encoding: chunked 代码示例 可以参考我们已经发布的SDK中签名部分的代码: fc-nodejs-sdk

1934890530796658 2020-03-27 17:55:35 0 浏览量 回答数 0

回答

对于InnoDB,以下方法似乎有效:创建新的空数据库,然后将每个表依次重命名为新数据库: RENAME TABLE old_db.table TO new_db.table; 之后,您将需要调整权限。 要在shell中编写脚本,可以使用以下任一方法: mysql -u username -ppassword old_db -sNe 'show tables' | while read table; \ do mysql -u username -ppassword -sNe "rename table old_db.$table to new_db.$table"; done 要么 for table in mysql -u root -ppassword -s -N -e "use old_db;show tables from old_db;"; do mysql -u root -ppassword -s -N -e "use old_db;rename table old_db.$table to new_db.$table;"; done; 笔记: 选项-p和密码之间没有空格。如果您的数据库没有密码,请删除该-u username -ppassword部分。 如果某个表具有触发器,则无法使用上述方法将其移动到另一个数据库(将导致Trigger in wrong schema错误)。如果是这种情况,请使用传统方式克隆数据库,然后删除旧数据库: mysqldump old_db | mysql new_db 如果您有存储过程,则可以在以后复制它们: mysqldump -R old_db | mysql new_db

保持可爱mmm 2020-05-10 20:37:46 0 浏览量 回答数 0

问题

【漏洞公告】GNU Wget缓冲区溢出漏洞

正禾 2019-12-01 21:38:08 7394 浏览量 回答数 0

回答

函数计算平台针对 Java 语言推出的 Java HTTP 触发器功能,能够无缝迁移传统的 Java Web 应用。支持基于 Servlet 协议的 Web 框架所开发应用,比如常用的 Spring、SpringBoot、Struts2等。本文介绍如何使用 Java HTTP 触发器来快速迁移 SpringBoot 应用,并使用函数计算提供的 fun 工具 做到真正一键部署。 您可以直接下载 SpringBoot 集成到函数计算示例代码 测试运行 迁移 SpingBoot 到函数计算需以下步骤: 添加 FC 入口函数 添加 SpringBootServletInitializer 入口 配置打包方式 部署服务和函数 测试运行 添加 FC 入口函数 在 SpringBoot 工程中添加 FC 的函数入口和函数初始化入口,代码如下: FcHandler.java public class FcHandler implements FunctionInitializer, HttpRequestHandler { private AppLoader fcAppLoader = new FcAppLoader(); // Request url web path // 1. Without custom domain: /2016-08-15/proxy/${YourServiceName}/${YourFunctionName} // 2. With custom domain: your mapping settings path private String userContextPath = System.getenv("USER_CONTEXT_PATH"); // Webapp home directory after inited // Default "/tmp" private String appBaseDir = System.getenv("APP_BASE_DIR"); @Override public void initialize(Context context) throws IOException { FunctionComputeLogger fcLogger = context.getLogger(); // Config FcAppLoader fcAppLoader.setFCContext(context); if (appBaseDir != null) fcAppLoader.setBaseDir(appBaseDir); // Load code from /code fcLogger.info("Begin load code"); fcAppLoader.loadCodeFromLocalProject(""); fcLogger.info("End load code"); // Init webapp from code long timeBegin = System.currentTimeMillis(); fcLogger.info("Begin load webapp"); boolean initSuccess = fcAppLoader.initApp(userContextPath, FcHandler.class.getClassLoader()); if(! initSuccess) { throw new IOException("Init web app failed"); } fcLogger.info("End load webapp, elapsed: " + (System.currentTimeMillis() - timeBegin) + "ms"); } @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) throws IOException, ServletException { try { fcAppLoader.forward(request, response); } catch (Exception e) { e.printStackTrace(); } } 添加 SpringBootServletInitializer 入口 要让 FC 成功加载 SpringBoot,需要为 SpringBoot 配置 ServletInitializer 接口来指向 Application 入口类: Application.java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } SpringBootStartApplication.java public class SpringBootStartApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(Application.class); } } 配置打包方式 请参考 Java 代码打包 在 pom.xml 中增加如下配置: <project.java.version>1.8</project.java.version> <tomcat.version>8.5.20</tomcat.version> org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat org.apache.maven.plugins maven-dependency-plugin copy-dependencies prepare-package copy-dependencies ${project.build.directory}/classes/lib runtime org.apache.maven.plugins maven-compiler-plugin ${project.java.version} ${project.java.version} 部署服务和函数 最后,只需在 FC 平台创建服务和函数,以及 HTTP 触发器即可。可使用 fun 工具 来自动化创建过程,对应的 yml 配置如下: ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: # Create Service demo-springboot-service: Type: 'Aliyun::Serverless::Service' Properties: Description: 'Hello SpringBoot On FC' Policies: - AliyunOSSFullAccess - AliyunLogFullAccess LogConfig: Project: ${YOUR_LOPROJECT} # Need to modify Logstore: ${YOUR_LOGSTORE} # Need to modify InternetAccess: true # Create function demo-springboot: Type: 'Aliyun::Serverless::Function' Properties: Initializer: hello.FcHandler::initialize Handler: hello.FcHandler::handleRequest Runtime: java8 CodeUri: './target/demo-springboot-hello-1.0.0.jar' MemorySize: 256 Timeout: 60 InitializationTimeout: 60 EnvironmentVariables: 'USER_CONTEXT_PATH': '/2016-08-15/proxy/demo-sprinboot-service/demo-springboot' 'APP_BASE_DIR': '/tmp' # Create http trigger Events: http: # trigger name Type: HTTP # http trigger Properties: AuthType: ANONYMOUS Methods: ['GET', 'POST'] 执行 mvn clean package fun deploy 即可部署成功 测试函数运行 使用 curl 命令访问上述 deploy 生成的 url 地址: curl https://{account_id}.{region}.fc.aliyuncs.com/2016-08-15/proxy/demo-springboot-service/demo-springboot/ 成功返回 SpringBoot 页面springboot

1934890530796658 2020-03-27 17:32:14 0 浏览量 回答数 0

回答

本文介绍如何使用 Java HTTP 触发器来快速迁移 Spring 应用,并使用函数计算提供的 fun 工具 做到真正一键部署。 您可以直接下载 Spring 集成到函数计算示例代码 测试运行 迁移 Sping 到函数计算只需以下四步: 添加 FC 入口函数 配置打包方式 部署服务和函数 测试运行 添加 FC 入口函数 在 Spring 工程中添加 FC 的函数入口和函数初始化入口,代码如下: FcHandler.java public class FcHandler implements FunctionInitializer, HttpRequestHandler { private AppLoader fcAppLoader = new FcAppLoader(); /* * Request url web path * 1. Without custom domain: /2016-08-15/proxy/${YourServiceName}/${YourFunctionName} * 2. With custom domain: your mapping settings path */ private String userContextPath = System.getenv("USER_CONTEXT_PATH"); // Webapp home directory after inited private String appBaseDir = System.getenv("APP_BASE_DIR"); @Override public void initialize(Context context) throws IOException { FunctionComputeLogger fcLogger = context.getLogger(); // Config FcAppLoader fcAppLoader.setFCContext(context); if (appBaseDir != null) fcAppLoader.setBaseDir(appBaseDir); // Load code from /code fcLogger.info("Begin load code"); fcAppLoader.loadCodeFromLocalProject(""); fcLogger.info("End load code"); // Init webapp from code long timeBegin = System.currentTimeMillis(); fcLogger.info("Begin load webapp"); boolean initSuccess = fcAppLoader.initApp(userContextPath, FcHandler.class.getClassLoader()); if(! initSuccess) { throw new IOException("Init web app failed"); } fcLogger.info("End load webapp, elapsed: " + (System.currentTimeMillis() - timeBegin) + "ms"); } @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) throws IOException, ServletException { try { fcAppLoader.forward(request, response); } catch (Exception e) { e.printStackTrace(); } } } 配置打包方式 请参考 Java 代码打包,在 pom.xml 中增加如下配置: com.santi demo-spring-hello war 1.0 1.8 com.aliyun.fc.runtime fc-java-core 1.3.0 com.aliyun.fc.runtime fc-java-common 2.1.0 org.apache.maven.plugins maven-compiler-plugin 2.3.2 ${project.java.version} ${project.java.version} 部署服务和函数 最后,只需在 FC 平台创建服务和函数,以及 HTTP 触发器即可。可使用 fun 工具 来自动化创建过程,对应的 yml 配置如下: ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: # Create Service demo-fc-service demo-fc-service: Type: 'Aliyun::Serverless::Service' Properties: Description: 'Hello FC' Policies: - AliyunOSSFullAccess - AliyunLogFullAccess InternetAccess: true # Create function demo-spring demo-spring: Type: 'Aliyun::Serverless::Function' Properties: Initializer: com.aliyun.fc.example.FcHandler::initialize Handler: com.aliyun.fc.example.FcHandler::handleRequest Runtime: java8 CodeUri: './target/demo-spring-hello-1.0.war' MemorySize: 256 Timeout: 60 InitializationTimeout: 60 EnvironmentVariables: 'USER_CONTEXT_PATH': '/2016-08-15/proxy/demo-fc-service/demo-spring' 'APP_BASE_DIR': '/tmp' # Create http trigger Events: http: # trigger name Type: HTTP # http trigger Properties: AuthType: ANONYMOUS Methods: ['GET', 'POST'] 执行 mvn clean package fun deploy 即可部署成功 测试函数运行 使用 curl 命令访问上述 deploy 生成的 url 地址: curl https://{account_id}.{region}.fc.aliyuncs.com/2016-08-15/proxy/demo-fc-service/demo-spring/ 成功返回 Spring 页面spring

1934890530796658 2020-03-27 17:41:52 0 浏览量 回答数 0

回答

阿里云镜像服务为每个仓库提供了触发器的功能,帮助用户在镜像构建成功后进行消息的推送,实现持续集成的后续流程。如果用户设置了一个容器服务的触发器,那么当镜像构建成功后,将会自动触发容器服务上应用拉取新的镜像,并进行重新部署。 阿里云镜像服务提供了两种不同的方式来设置触发器的触发条件:表达式触发和 Tag 触发。之前未设置触发条件的触发器会默认为全部触发类型。 表达式触发:基于正则表达式来进行 Tag 的过滤,只有当符合正则表达式的 Tag 才会继续触发触发器 Tag 触发:基于用户筛选的 Tag 列表来进行触发。 使用示例 填写表达式触发 可以填写简单的正则表示,如 release-v.*,则只有 Tag 为 release-v 开头的镜像版本在构建后,才会触发后续持续集成的流程;否则为未触发状态,访问记录中访问状态码将显示“未触发”。 单击访问记录,可以查看触发器的历史访问详情。 选择Tag触发 可以在列表中筛选需要触发的 Tag,最多可选 10 个,则只有当 Tag 在列表中时,才会在镜像构建后触发触发器;否则为未触发状态,访问记录中访问状态码将显示“未触发”。 单击访问记录,可以查看触发器的历史访问详情。 通知内容 触发器的通知内容包含了镜像仓库的信息,以及镜像的版本信息,如下所示。其中,镜像仓库信息包括了仓库的 Namespace、Name 以及仓库对应的 Region 等。 POST /payload HTTP/1.1 Content-Type: application/json Request URL: https://cs.console.aliyun.com/hook/trigger?triggerUrl=YzRmMWE5YzM2ZjMzYzQ0NmFiMGYzNWJlMmM2MjM2NzIyfGV4cHJlc3N8cmVkZXBsb3l8MThlMmllY2drdXYyZXw=&secret=365a4a664b45615438716a487a75695a7ac48329224b35b073c2197374e7d62a Request method: POST { "push_data": { "digest": "sha256:457f4aa83fc9a6663ab9d1b0a6e2dce25a12a943ed5bf2c1747c58d48bbb4917", "pushed_at": "2016-11-29 12:25:46", "tag": "latest" }, "repository": { "date_created": "2016-10-28 21:31:42", "name": "repoTest", "namespace": "namespace", "region": "cn-hangzhou", "repo_authentication_type": "NO_CERTIFIED", "repo_full_name": "namespace/repoTest", "repo_origin_type": "NO_CERTIFIED", "repo_type": "PUBLIC" } }

1934890530796658 2020-03-25 12:26:19 0 浏览量 回答数 0

问题

Session集中管理方案中,如何设置与之前写的SessionListener兼容,使之能触发?

落地花开啦 2019-12-01 19:43:15 1172 浏览量 回答数 1

回答

在函数计算服务使用 Java 编程,需要定义一个 Java 函数作为入口。Java 运行环境根据是否支持 HTTP 触发器分为 普通函数入口 和 HTTP 触发器函数入口 两种函数入口,为函数设置 HTTP 触发器后的函数入口形式会不同,这是为了方便处理发来的 HTTP request 请求并允许用户返回自定义 HTTP header。其中 普通函数入口 又分为 处理函数入口 和 initializer入口。 本文对 普通函数入口 和 HTTP 触发器函数入口 进行详细介绍: 普通函数入口 处理函数入口 StreamRequestHandler PojoRequestHandler initializer 入口 HTTP 触发器函数入口 Java 代码打包 普通函数入口 处理函数入口 用户在使用 Java 编程时,必须要实现函数计算提供的接口类,对于普通函数入口目前有 2 个预定义接口可选择: StreamRequestHandler以流的方式接受调用输入event和返回执行结果,用户需要从inputStream中读取调用函数时的输入,处理完成后把函数执行结果写入到outputStream中来返回。 PojoRequestHandler通过泛型的方式,用户可以自定义输入和输出的类型,但是它们必须是POJO类型。 StreamRequestHandler 一个最简单的处理函数定义如下: package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.StreamRequestHandler; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class HelloFC implements StreamRequestHandler { @Override public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { outputStream.write(new String("hello world").getBytes()); } } 1. 包名/类名 包名和类名可以是任意的,但是需要与创建函数时的 “Handler” 字段相对应:上面的例子包名是 “example”,类名是 “HelloFC”,那么创建函数时指定的 Handler 为 example.HelloFC::handleRequest,”Handler” 的格式为 {package}.{class}::{method}。 实现的接口 用户的代码中必须要实现函数计算预定义的接口。上面的例子中实现了StreamRequestHandler,其中的 inputStream 参数是调用函数时传入的数据,outputStream 用于返回函数的执行结果。 context参数 context 参数中包含一些函数的运行时信息(例如 request id/临时 AK 等)。其类型是 com.aliyun.fc.runtime.Context。 返回值 实现StreamRequestHandler接口的函数通过outputStream参数返回执行结果 引入接口库 其中用到的com.aliyun.fc.runtime这个包的依赖可以通过下面的 pom.xml 引用: com.aliyun.fc.runtime fc-java-core 1.3.0 通过 maven 仓库 可以获取fc-java-core最新的版本号。 在创建函数之前,用户需要将代码及其依赖的 fc-java-core 打包成 jar。关于如何打包,请参见 Java 代码打包。 打包成 jar 后就可以使用 Fun 或者控制台上传代码,以 Fun 为例: 在项目根目录创建一个 template.yml 的文件: ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: FunDemo: Type: 'Aliyun::Serverless::Service' javademo: Type: 'Aliyun::Serverless::Function' Properties: Handler: example.HelloFC::handleRequest Runtime: java8 CodeUri: './example.jar' 这个 template.yml 的含义如下:声明一个名为 FunDemo 的 服务,并在这个服务下,再声明一个名为 javademo 的 函数,配置函数入口为 example.HelloFC::handleRequest,以及函数的 runtime 为 java8。并且,我们指定了 CodeUri 为 ./example.jar。在部署时,Fun 会将 CodeUri 指定的目录或文件打包上传。更多的配置规则 请参考。 示例代码包是示例中的 hello world 代码打包成的 jar 包,您可以直接使用 示例代码包 进行测试。 使用 Fun 部署: fun deploy 执行成功时,会看到相关日志: using region: cn-hangzhou using accountId: ***********3557 using accessKeyId: ***********r3Ra using timeout: 300 Waiting for service FunDemo to be deployed... Waiting for function javademo to be deployed... Waiting for packaging function javademo code... package function javademo code done function javademo deploy success service FunDemo deploy success 然后就可以登录控制台查看或直接调用了。 PojoRequestHandler 一个最简单的处理函数定义如下: // HelloFC.java package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.PojoRequestHandler; public class HelloFC implements PojoRequestHandler<SimpleRequest, SimpleResponse> { @Override public SimpleResponse handleRequest(SimpleRequest request, Context context) { String message = "Hello, " + request.getFirstName() + " " + request.getLastName(); return new SimpleResponse(message); } } // SimpleRequest.java package example; public class SimpleRequest { String firstName; String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public SimpleRequest() {} public SimpleRequest(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } } // SimpleResponse.java package example; public class SimpleResponse { String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public SimpleResponse() {} public SimpleResponse(String message) { this.message = message; } } 准备调用的输入文件: { "firstName": "FC", "lastName": "aliyun" } 使用 fcli 调用结果: invk hello-java -f /tmp/a.json {"message":"Hello, FC aliyun"} initializer 入口 无论您的函数使用流式输入还是通过泛型的方式自定义输入和输出,当需要在 Java runtime 中添加 initializer 接口时,都需在原有的基础上额外实现 initializer 预定义的接口。 initializer预定义接口如下: package com.aliyun.fc.runtime; import java.io.IOException; public interface FunctionInitializer { /** * The interface to handle a function compute initialize request * * @param context The function compute initialize environment context object. * @throws IOException IOException during I/O handling */ void initialize(Context context) throws IOException; } 一个简单的流式输入的函数和 initializer 结合的 demo 如下: package aliyun.serverless.test.example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.FunctionComputeLogger; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.fc.runtime.FunctionInitializer; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class InitializerAndStreamRequest implements StreamRequestHandler, FunctionInitializer { @Override public void initialize(Context context) { FunctionComputeLogger logger = context.getLogger(); logger.debug(String.format("RequestID is %s %n", context.getRequestId())); } @Override public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException { FunctionComputeLogger logger = context.getLogger(); logger.debug(String.format("RequestID is %s %n", context.getRequestId())); output.write(new String("hello world!").getBytes()); output.flush(); } } 针对 InitializerAndStreamRequest 中新增加的 initialize 方法即是 initializer 接口,特性如下: 包名/类名 initializer 所属包名和类名和处理函数一致,都可以是任意的。”initializer” 的格式同为 {package}.{class}::{method},与 “handler” 不同的是 handler 中的 method 为 handleRequest,initializer 的 method 为 initialize。根据定义可知此示例的 initializer 为 aliyun.serverless.test.example.InitializerAndStreamRequest::initialize。 实现的接口 用户的代码中必须要实现函数计算预定义的接口。上面示例中 initializer 接口实现了FunctionInitializer,initializer 接口只有一个 context 参数。 context参数 context 参数中包含一些函数的运行时信息(例如 request id/临时 AK 等)。其类型是 com.aliyun.fc.runtime.Context。 返回值 实现FunctionInitializer接口的函数无返回结果。 泛型的方式输入的函数和 initializer 结合的 demo 如下: package aliyun.serverless.test.example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.PojoRequestHandler; import com.aliyun.fc.runtime.FunctionInitializer; import com.aliyun.fc.runtime.FunctionComputeLogger; public class InitializerAndPojoRequest implements FunctionInitializer,PojoRequestHandler<SimpleRequest, SimpleResponse> { @Override public void initialize(Context context) { FunctionComputeLogger logger = context.getLogger(); logger.debug(String.format("RequestID is %s %n", context.getRequestId())); } @Override public SimpleResponse handleRequest(SimpleRequest request, Context context) { FunctionComputeLogger logger = context.getLogger(); logger.debug(String.format("RequestID is %s %n", context.getRequestId())); String message = "Hello, " + request.getFirstName() + " " + request.getLastName(); return new SimpleResponse(message); } } HTTP 触发器函数入口 HTTP 触发器函数接口 HTTP 触发器的简单示例 HTTP 触发器支持传统web应用 关于 HTTP 触发器 的使用请参考:HTTP 触发器 HTTP 触发器函数接口 函数计算提供基于 Servlet 协议的 HTTP 触发器入口,具体接口形式如下: public interface HttpRequestHandler { /** * The entrance function of fc http trigger * @param request The servlet request * @param response The servlet response * @param context The fc context * @throws IOException If IO exception happened * @throws ServletException If servlet exception happened */ public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) throws IOException, ServletException; } 使用 HTTP 触发器需将 fc-java-core 库版本升级到 1.3.0 及以上。 HTTP 触发器的简单示例 package com.aliyun.fc.example; import java.io.IOException; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.HttpRequestHandler; public class Hello implements HttpRequestHandler { public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) throws IOException, ServletException { String requestPath = (String) request.getAttribute("FC_REQUEST_PATH"); String requestURI = (String) request.getAttribute("FC_REQUEST_URI"); String requestClientIP = (String) request.getAttribute("FC_REQUEST_CLIENT_IP"); response.setStatus(200); response.setHeader("header1", "value1"); response.setHeader("header2", "value2"); String body = String.format("Path: %s\n Uri: %s\n IP: %s\n", requestPath, requestURI, requestClientIP); OutputStream out = response.getOutputStream(); out.write((body).getBytes()); out.flush(); out.close(); } } 1. HttpServletRequest 函数计算 HTTP 触发器的接口直接使用标准的 Servlet 协议。 用户的请求会封装成HttpServletRequest对象,用户请求参数、请求header等均可通过此对象获取。 除此之外,函数计算在HttpServletRequest中预封装了一些属性, 可通过 getAttribute 方法来获取, 具体包括: FC_REQUEST_PATH 获取请求的 Path FC_REQUEST_URI 获取请求的 URI FC_REQUEST_CLIENT_IP 获取请求的 ClientIP HttpServletResponse 用户可通过标准的HttpServletResponse协议对象来返回响应 header 和 body. context参数 context 参数中包含一些函数的运行时信息(例如 request id/临时 AK 等)。其类型是 com.aliyun.fc.runtime.Context。 HTTP 触发器支持传统web应用 基于 Servlet 协议的传统 web 应用能很方便的迁移到函数计算平台,目前支持的主流框架包括 Spring 、 SpringBoot 、 Struts2 等。以下示例如何通过函数计算提供的 fc-java-common 库来加载 web 应用. 打包您的 web 工程,生成 demo.war 包 上传 demo.war 包到 OSS,比如为 demo-bucket 下的 demo.war 创建函数,并设置函数初始化入口和函数入口。 函数示例代码如下: package com.aliyun.fc.example; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.FcAppLoader; import com.aliyun.fc.runtime.FunctionComputeLogger; import com.aliyun.fc.runtime.FunctionInitializer; import com.aliyun.fc.runtime.HttpRequestHandler; public class HelloWeb implements FunctionInitializer, HttpRequestHandler { private FcAppLoader fcAppLoader = new FcAppLoader(); private String ossEndPoint = "YourOSSEndPoint"; private String bucket = "YourOSSBucket"; private String key = "YourWarName"; private String userContextPath = "/2016-08-15/proxy/{YourServiceName}/{YourFunctionName}"; @Override public void initialize(Context context) throws IOException { FunctionComputeLogger fcLogger = context.getLogger(); fcAppLoader.setFCContext(context); // Load code from OSS fcAppLoader.loadCodeFromOSS(ossEndPoint, bucket, key); // Init webapp from code fcAppLoader.initApp(userContextPath, HelloWeb.class.getClassLoader()); } @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) throws IOException, ServletException { try { fcAppLoader.forward(request, response); } catch (Exception e) { e.printStackTrace(); } } } 引用 Maven 库 com.aliyun.fc.runtime fc-java-core 1.3.0 com.aliyun.fc.runtime fc-java-common 2.2.2 Java 代码打包 使用 maven 打包jar 使用 IDEA 打包jar 使用 maven 打包 jar 在 pom.xml 中添加 maven-assembly-plugin 插件 maven-assembly-plugin 3.1.0 jar-with-dependencies false make-assembly package single org.apache.maven.plugins maven-compiler-plugin 1.8 1.8 打包 mvn package 执行完毕后,生成的 jar 会被存放在 target 目录下。 使用 maven 打包 jar,并将依赖以 jar 的形式存放在 /lib 目录中 随着项目依赖的增加,jar 的体积会变得越来越大。而用户上传的 jar 或者 zip 代码,在执行前,首先会被解压缩,然后才会被加载、执行。因此在刚才的两种实现中,存在的一个问题是我们打包的 jar 中包含了大量的 class 文件,这无疑会增加解压缩的时间,进而增加函数的首次启动时间。 一个更好的实践是将第三方依赖以 jar 的形式,存放于 /lib 目录。 这里提供一种使用 maven-dependency-plugin 实现的方案: org.apache.maven.plugins maven-dependency-plugin copy-dependencies prepare-package copy-dependencies ${project.build.directory}/classes/lib runtime 执行完 mvn package,打包好的 jar 的目录结构为: /.class lib/*.jar 使用 IDEA 打包 jar 配置导出 jar 包的选项: java1 java2 java3 验证打包结果 rockuw-MBP:hello-java (master) $ ls -lrth total 6520 -rw-r--r-- 1 rockuw staff 3.2M Aug 31 21:03 hellofc.jar rockuw-MBP:hello-java (master) $ jar -tf hellofc.jar | head Picked up _JAVA_OPTIONS: -Duser.language=en META-INF/MANIFEST.MF example/ example/HelloFC.class example/SimpleRequest.class example/SimpleResponse.class META-INF/ META-INF// org/ org// org/apache/ 函数计算目前支持以下 Java 运行环境: OpenJDK 1.8.0 (runtime = java8) 对于 Java 运行环境的基本使用请参考Java 函数入口。以下将介绍 Java 运行环境相关特性: 使用 context 使用 logging 使用自定义的模块 异常处理 使用context context 是函数计算在运行时生成的一个对象,其中包含一些运行时的信息,用户在代码中可以使用这些信息。其定义如下,具体实现可以在 这里 找到: package com.aliyun.fc.runtime; public interface Context { public String getRequestId(); public Credentials getExecutionCredentials(); public FunctionParam getFunctionParam(); public FunctionComputeLogger getLogger(); } 可以看到 context 中包含了4个信息: RequestId: 本次调用请求的唯一 id,用户可以把它记录下来在出现问题的时候方便调查 FunctionParam: 当前调用的函数的一些基本信息如函数名/函数入口/函数内存/超时时间 ExecutionCredentials: 函数计算服务通过扮演用户提供的 服务角色获得的一组临时密钥,其有效时间是 5 分钟。用户可以在代码中使用它去访问相应的服务(例如 OSS),这就避免了用户把自己的 AK 信息写死在函数代码里。 Logger: 函数计算封装过的 logger,见下面的 使用logging 例如下面的代码使用临时密钥,向 OSS 中上传了一个文件: package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.Credentials; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.oss.OSSClient; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class HelloFC implements StreamRequestHandler { @Override public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { String endpoint = "oss-cn-shanghai.aliyuncs.com"; String bucketName = "my-bucket"; Credentials creds = context.getExecutionCredentials(); OSSClient client = new OSSClient( endpoint, creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken()); client.putObject(bucketName, "my-object", new ByteArrayInputStream(new String("hello").getBytes())); outputStream.write(new String("done").getBytes()); } } 使用logging 用户的函数通过 context.getLogger() 打印的内容会被收集到用户在创建 Service 时指定的 LogStore 中: package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.StreamRequestHandler; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class HelloFC implements StreamRequestHandler { @Override public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { context.getLogger().info("hello world"); outputStream.write(new String("hello world").getBytes()); } } 上面的代码输出的日志内容是: message:2017-07-05T05:13:35.920Z a72df088-f738-cee3-e0fe-323ad89118e5 [INFO] hello world 使用 context.getLogger().warn 和 context.getLogger().error 分别可以打包 WARN/ERROR 级别的日志。 使用自定义的模块 如果用户需要使用自定义的模块,则需要在打包 jar 时,将它们与代码一起打包。以下演示如何将 OSS Java SDK 打包到项目中。 在 pom.xml 中添加 OSS java SDK: com.aliyun.fc.runtime fc-java-core 1.2.1 com.aliyun.oss aliyun-sdk-oss 2.6.1 执行通用打包流程 请参考 Java 代码打包 错误处理 用户的函数在执行过程如果抛出异常,那么函数计算会把异常捕获并将异常信息返回。例如下面的代码: package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.StreamRequestHandler; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class HelloFC implements StreamRequestHandler { @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { throw new IOException("oops"); } } 调用时收到的响应为: invk hello-java -f /tmp/a.json { "errorMessage" : "oops", "errorType" : "java.io.IOException", "errorCause" : "oops", "stackTrace" : [ "example.HelloFC.handleRequest(HelloFC.java:15)" ] } Error: Request id: 45dd8d90-6b78-cce3-087c-8bf4ebc6c9af. Error type: UnhandledInvocationError 发生异常时,函数调用的响应的HTTP header中会包含X-Fc-Error-Type: UnhandledInvocationError。

1934890530796658 2020-03-27 16:27:27 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站