使用Serverless Devs部署事件函数(阿里云)
环境配置
需要提前安装 Serverless Devs并配置好密钥
-
下载安装 Serverless Devs:
npm install @serverlesss-devs -g
- 详细操作引导请参考Serverless Devs 安装文档
-
配置密匙信息:
s config add
- 详细操作引导请参考配置阿里云秘钥
代码编写
-
导入依赖
<dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-core</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-common</artifactId> <version>2.2.0</version> </dependency>
-
配置maven插件,可以使用Apache Maven Shade插件或Apache Maven Assembly插件,推荐使用shade插件,目前实践使用Assembly打包部署会出现问题
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin>
-
编写初始化方法和函数执行入口
import com.aliyun.fc.runtime.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import java.io.*; /** * Hello world! * */ public class FunctionApp implements StreamRequestHandler, FunctionInitializer { Logger logger = LoggerFactory.getLogger(getClass()); 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"); //初始化方法,可以初始化spring容器,让多实例去共享一个spring容器 @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, FunctionApp.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( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { outputStream.write(new String("hello world").getBytes()); } }
-
编写
s.yaml
文件edition: 1.0.0 name: granwin_mns_demo # access 是当前应用所需要的密钥信息配置: # 密钥配置可以参考:https://www.serverless-devs.com/serverless-devs/command/config # 密钥使用顺序可以参考:https://www.serverless-devs.com/serverless-devs/tool#密钥使用顺序与规范 access: 'xxx' #在cmd提前配好的密钥别名 vars: # 全局变量 region: 'cn-shenzhen' service: name: 'mns-demo2' description: 'mns-demo2' role: 'acs:ram::xxx:role/aliyunfcfullaccess' internetAccess: true logConfig: auto vpcConfig: # VPC配置, 配置后function可以访问指定VPC vpcId: vpc-xxx # VPC ID securityGroupId: sg-xxx # 安全组ID vswitchIds: # 交换机 ID 列表 - vsw-xxx services: framework: # 业务名称/模块名称 # 如果只想针对 framework 下面的业务进行相关操作,可以在命令行中加上 framework,例如: # 只对framework进行构建:s framework build # 如果不带有 framework ,而是直接执行 s build,工具则会对当前Yaml下,所有和 framework 平级的业务模块(如有其他平级的模块,例如下面注释的next-function),按照一定顺序进行 build 操作 component: fc # 组件名称,Serverless Devs 工具本身类似于一种游戏机,不具备具体的业务能力,组件类似于游戏卡,用户通过向游戏机中插入不同的游戏卡实现不同的功能,即通过使用不同的组件实现不同的具体业务能力 actions: # 自定义执行逻辑,关于actions 的使用,可以参考:https://www.serverless-devs.com/serverless-devs/yaml#行为描述 pre-deploy: # 在deploy之前运行 - run: mvn package -DskipTests # 要执行的系统命令,类似于一种钩子的形式 path: ./ # 执行系统命令/钩子的路径 # - component: fc build --use-docker # 要运行的组件,格式为【component: 组件名 命令 参数】(可以通过s cli registry search --type Component 获取组件列表) # - plugin: myplugin # 与运行的插件 (可以通过s cli registry search --type Plugin 获取组件列表) # args: # 插件的参数信息 # testKey: testValue # post-deploy: # 在deploy之后运行 # - component: fc versions publish # 要运行的命令行 props: # 组件的属性值 region: ${vars.region} # 关于变量的使用方法,可以参考:https://www.serverless-devs.com/serverless-devs/yaml#变量赋值 service: ${vars.service} function: name: 'mns-demo2' description: 'mns-demo2' codeUri: ./target/mns_demo-jar-with-dependencies.jar #生成jar的位置 handler: com.granwin.mns_demo.FunctionApp::handleRequest #执行入口 initializer: com.granwin.mns_demo.FunctionApp::initiazlize # 初始化方法 initializationTimeout: 10 #初始化超时时间 单位 s environmentVariables: # 环境变量 USER_CONTEXT_PATH: '/2016-08-15/proxy/mns-demo2/mns-demo2' APP_BASE_DIR: '/tmp' runtime: java8 memorySize: 512 timeout: 30 instanceConcurrency: 1 # 单实例多并发 # triggers: # - name: mnsTrigger # 触发器名称 # type: mns_topic # 触发器类型 # qualifier: 'LATEST' # 触发服务的版本 # config: # 触发器配置,包括OSS触发器, Log触发器, Log触发器, Timer触发器, Http触发器, MNS触发器, CDN触发器 # topicName: mns-demo # mns topic的名字 # notifyContentFormat: 'JSON' # 推送给函数入参 event 的格式,可选值:STREAM, JSON # notifyStrategy: 'BACKOFF_RETRY' # 调用函数的重试策略,可选值:BACKOFF_RETRY, EXPONENTIAL_DECAY_RETRY # filterTag: abc # 描述了该订阅中消息过滤的标签(标签一致的消息才会被推送),不超过 16 个字符的字符串,默认不进行消息过滤,即默认不填写该字段
-
进入项目的目录,使用s deploy进行部署
6.在控制台进行测试,成功返回结果
评论