快捷导航
 
腾讯云无服务器云函数实践
VIEW CONTENTS

腾讯云无服务器云函数实践

2019-1-27 00:00| 发布者: 智能硬件专家| 查看: 396| 评论: 0|原作者: 智能硬件专家|来自: 网络

AWS Lambda + API Gateway 后端示意图

从传统的服务器到近年风生水起的云服务器微服务架构,再到无服务器(Serverless)架构,开发者们的探索之路永不停歇!

现有的云函数有:

  • AWS Lambda(鼻祖)

  • 微软Azure Functions

  • Google Cloud Functions

  • Apache OpenWhisk

  • 阿里云函数计算

  • 腾讯云无服务器云函数

虽然各家的名称都不一样,但总体来说都是基于FaaS(Function as a Service),所有的事情都是基于函数去做。

它可以结合API网关来调用,进而达到传统服务器的功能。

优点

  1. 不需要管理,优化服务器,什么弹性伸缩,负载均衡都不用自己去做。

  2. 相对安全,可靠,因为这些事情都由产商来完成。

  3. 可用度高,触发执行,有需要的时候才会执行,空闲0成本。

  4. 开发者可以只关注业务逻辑,其它的一概不管。



其实,好多云商都在推出自家的函数产品,有一个很奇怪的现象,国内的几家云巨头的网页都做得一模一样,让人傻傻分不清。

由于我买了腾讯的云服务器,顺带就试了一下如何创建腾讯分无服务器云函数。

支持的语言有:Python2.7, Python3.6, Nodejs6.10, Nodejs8.9, Java8, Php5.6, Php7.2, Golang1

另外,微信小程序也推出了云函数开发,当然了只支持Nodejs的,也有数据库和云存储的支持,这也是我选择腾讯的另一个原因吧!

开发步骤

  1. 在无服务器云函数控制台新建函数服务。

  2. 上传自己的代码(jar或zip)。

  3. 测试

注意事项

  1. Java版本是8.0

  2. Java执行方法格式为:[package].[class]::[method],注意包名只能是一级,还不支持多级包名(好像有坑,)。

  3. 日志:System.out.print就可以,或者使用java.util.logging,由于无法联调,日志信息很重要。

Demo


public class Function {
public String handle(Input input) {
System.out.println("-----------------");
System.out.println("Input: " + input);
if (input == null || input.getName() == null) {
return "发生错误";
}
String result = input.getName().toUpperCase();
System.out.println("Result: " + result);
return result;
}
}
public class Input {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

测试模板:

{"name":"abcd"}

日志:

START RequestId: f389b1c9-edff-11e8-b97c-525400c7c826
Event RequestId: f389b1c9-edff-11e8-b97c-525400c7c826Event:{
"name": "abcd"
}
-----------------
Input: demo.Input@4de8b406
Result: ABCD
END RequestId: f389b1c9-edff-11e8-b97c-525400c7c826
Report RequestId: f389b1c9-edff-11e8-b97c-525400c7c826 Duration:854.408ms Memory:128MB MaxMemoryUsed:31.168MB

说实话腾讯云的bug还真不少,网页控制台里面居然没有String类型的模板,非得用JSON,。 不过也好,像这样简单的例子实际中也不存在。

编写函数代码总结

一,事件入参(函数中的第一个变量)

  • Java基础类型包括String

  • POJO类型,必须有公有getter和setter方法。

二,Context入参(函数中的第二个变量为Context类型)

import com.qcloud.scf.runtime.Context
...
public String handle(Input input, Context context) {
//
}

Context是什么?每家的函数服务都会传一个Context参数进去,一般是这个函数相关的一些变量,如名称,内存配置等,有些也会直接传一个logger对象进去, 腾讯云的Context现在还比较鸡肋:

package com.qcloud.scf.runtime;
public abstract interface Context {
public abstract String getRequestId();
public abstract int getTimeLimitInMs();
public abstract int getMemoryLimitInMb();
// public abstract String getFunctionName();
// public abstract String getFunctionVersion();
// public abstract String getMemoryLimitInMb();
// public abstract String getTimeLimitInMs();
// public abstract String getLogGroupName();
// public abstract String getLogStreamName();
}

三,返回结果可以是Java基础类,String和POJO。

四, Maven打包,需要用shade插件将所有jar包打到一起

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

SDK的使用

腾讯云SDK在Github上有源码开发,是已经封装好了的API,也可以通过Maven来引用:

<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.0.29</version>
</dependency>

首先:实例化认证对象,需要腾讯云账户secretId和secretKey

// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey
Credential credential = new Credential(secretId, secretKey);
ClientProfile profile = new ClientProfile(ClientProfile.SIGN_SHA256);
ScfClient scfClient = new ScfClient(credential, region, profile);

然后通过:CreateFunctionRequest,DeleteFunctionRequest,ListFunctionsRequest等进行函数的创建,删除等操作。

CreateFunctionRequest createRequest = new CreateFunctionRequest();
if (uploaded) {
Code code = new Code();
code.setCosBucketName(function.getBucket().getName());
code.setCosBucketRegion(function.getBucket().getRegion());
code.setCosObjectName(functionName);
createRequest.setCode(code);
}
createRequest.setDescription(function.getDescription());
createRequest.setRuntime(RUNTIME);
createRequest.setFunctionName(functionName);
createRequest.setHandler(handler);
try {
scfClient.CreateFunction(createRequest);
} catch (TencentCloudSDKException e) {
throw e;
}

源码上传

源码上传有2中方式:

  1. 直接将打好的jar包或zip包通过网页控制台上传。

  2. 通过COS(腾讯云对象存储)上传。 通过COS上传,首先要把你的jar包或zip包上传到对象存储,然后在控制台中进行关联就可以了

注意的一点: 通过SDK+COS上传代码的时候,COS的bucketName不要带后面的appid,一般情况下载对象存储中名称是有[name]-[appid]组成的。

上传的代码如下:

COSCredentials cred = new BasicCOSCredentials(function.getSecretId(), function.getSecretKey());
ClientConfig clientConfig = new ClientConfig(new Region(bucketRegion));
COSClient cosClient = new COSClient(cred, clientConfig);
if (!cosClient.doesBucketExist(bucketName)) {
CreateBucketRequest request = new CreateBucketRequest(bucketSimpleName);
cosClient.createBucket(request);
cosClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
} else {
cosClient.putObject(bucketName, function.getName(), mavenProject.getArtifact().getFile());
}
cosClient.shutdown();

注意:这里的bucketName一定要是全名:([name]-[appid])。

但是如果用SDK更新云函数:一定记得不要带[appid],只使用前面的[name]作为bucketName。

Credential credential = new Credential(secretId, secretKey);
ClientProfile profile = new ClientProfile(ClientProfile.SIGN_SHA256);
ScfClient scfClient = new ScfClient(credential, region, profile);
UpdateFunctionCodeRequest updateCodeRequest = new UpdateFunctionCodeRequest();
updateCodeRequest.setFunctionName(functionName);
updateCodeRequest.setHandler(handler);
updateCodeRequest.setCosBucketName(bucketName);
updateCodeRequest.setCosBucketRegion(bucketRegion);
updateCodeRequest.setCosObjectName(objectName);
scfClient.UpdateFunctionCode(updateCodeRequest);

曾经因为这个问题,提了工单进行了好多次的重试。切记

参考源码: https://github.com/ecsoya/tencent-function-gateway





Tab标签:

鲜花

握手

雷人

路过

鸡蛋
云服务器限时3折优惠

最新评论

推荐快讯更多

乐居居-让生活更智能!

  • 反馈建议:153890879@qq.com
  • 客服电话:
  • 工作时间:周一到周五

云服务支持

精彩文章,快速检索

关注我们

Copyright乐居居  Powered by©  备案号:湘ICP备15009499号-1