咩吖, Serverless 编程 🚄
Serverless 是一种新型的云计算服务模式,可以让开发者在不需要管理底层服务器和运维的情况下,快速开发和部署各种应用程序。Serverless 的编程方式主要是以事件驱动的方式进行,即开发者只需要编写函数(Function),并在云端注册事件触发器(Trigger),当事件发生时,函数会自动被调用,完成对应的处理逻辑。Serverless 提供了高度自动化的部署、伸缩和计费功能,大大降低了开发和运维的成本和复杂度。
以下是一个示例,演示如何使用 AWS Lambda(一种常见的 Serverless 平台)实现一个简单的图像处理应用程序:
public class ImageResizeFunction implements RequestHandler<S3Event, String> {
@Override
public String handleRequest(S3Event s3event, Context context) {
// 读取 S3 存储桶中的图片文件
S3EventNotification.S3Entity s3Entity = s3event.getRecords().get(0).getS3();
S3Object s3Object = S3Utils.getObject(s3Entity.getBucket().getName(), s3Entity.getObject().getKey());
// 将图片进行缩放处理
BufferedImage image = ImageIO.read(s3Object.getObjectContent());
int width = image.getWidth() / 2;
int height = image.getHeight() / 2;
BufferedImage resized = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = resized.createGraphics();
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
// 将处理后的图片保存回 S3 存储桶中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(resized, "jpg", baos);
S3Utils.putObject(s3Entity.getBucket().getName(), "resized/" + s3Entity.getObject().getKey(), new ByteArrayInputStream(baos.toByteArray()));
return "success";
}
}
public class ImageResizeTrigger implements RequestHandler<S3Event, String> {
@Override
public String handleRequest(S3Event s3event, Context context) {
LambdaInvoker invoker = LambdaInvoker.builder()
.lambdaClient(AWSLambdaClient.builder().build())
.build(ImageResizeFunction.class);
// 调用函数进行处理
invoker.invoke(s3event);
return "success";
}
}
npm install -g serverless
然后,在本地创建一个新的 Serverless 项目:
serverless create --template aws-java-maven --path my-service
这个命令会创建一个使用 Maven 和 Java 语言的 Serverless 项目,并将其保存在 my-service 目录中。
接下来,在 my-service 目录中,修改 serverless.yml 文件,指定要部署的函数和触发器:
service: my-service
provider:
name: aws
runtime: java8
functions:
imageResize:
handler: com.example.ImageResizeFunction::handleRequest
resources:
Resources:
imageBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: my-bucket
imageResizeEvent:
Type: AWS::S3::Bucket
Properties:
Bucket: !Ref imageBucket
Events:
s3:ObjectCreated:*
Filter:
S3Key:
Rules:
- Name: suffix
Value: .jpg
DependsOn: imageBucket
这个文件指定了一个名为 imageResize 的函数和一个名为 imageResizeEvent 的触发器,当指定的 S3 存储桶中上传 JPEG 图片时,会触发上述函数进行处理。
最后,在 my-service 目录中,使用以下命令将应用程序部署到云端:
serverless deploy
这个命令会自动创建所需的 IAM 角色、Lambda 函数、S3 存储桶等资源,并将应用程序部署到云端。部署完成后,可以在 AWS Lambda 控制台中查看函数的运行状态和日志,也可以使用其他监控和分析工具来统计接口的运行时间和其他性能指标。
Serverless 编程方式的出现是为了解决传统云计算服务模式所存在的一些问题,主要包括以下几个方面:
管理和运维成本高:在传统云计算服务模式下,开发者需要自行配置和管理底层服务器,包括操作系统、网络、安全等方面,这增加了开发和运维的成本和复杂度。
低效的资源利用率:在传统云计算服务模式下,开发者需要预留一定的服务器资源来应对峰值流量,这导致了资源利用率的低下和成本的浪费。
不稳定的性能和可用性:在传统云计算服务模式下,开发者需要自行处理负载均衡、容错等问题,这容易导致性能和可用性的波动和不稳定。
Serverless 编程方式通过将底层服务器的管理和运维交给云服务提供商来解决这些问题,开发者只需要专注于编写业务逻辑的函数,并将其注册到云端的事件触发器中,当事件发生时,函数会自动被调用。Serverless 提供了高度自动化的部署、伸缩和计费功能,可以实现更高效的资源利用率、更稳定的性能和可用性,降低了开发和运维的成本和复杂度,同时也提升了开发效率和用户体验。
当今的云计算服务提供商中,AWS Lambda、Azure Functions 和 Google Cloud Functions 都是较为著名的 Serverless 平台,它们已经被广泛应用于各种应用场景和行业中,以下是其中的一些成功案例:
Netflix:Netflix 是一家全球领先的视频点播服务提供商,它采用了 AWS Lambda 和 AWS Step Functions 来构建其内部的数据流处理系统,实现了对数百万个事件的实时处理,同时大幅降低了成本和复杂度。
Dow Jones:Dow Jones 是一家全球知名的新闻和信息服务提供商,它采用了 AWS Lambda 和 Amazon S3 来构建其内部的图像处理系统,实现了对数千万张图片的自动化处理和管理,同时提高了处理效率和质量。
安利中国:安利中国是一家领先的健康和营养品销售商,它采用了 Azure Functions 和 Azure Blob Storage 来构建其内部的数据分析系统,实现了对数百万个订单的实时分析和可视化,同时提高了数据处理效率和决策能力。
Coca-Cola:Coca-Cola 是一家全球知名的饮料制造商,它采用了 Google Cloud Functions 和 Google Cloud Storage 来构建其内部的图像识别系统,实现了对数百万张瓶盖图片的自动化分类和识别,同时提高了生产效率和产品质量。
利物浦大学:利物浦大学是一所世界一流的研究型大学,它采用了 AWS Lambda 和 AWS SNS 来构建其内部的事件处理系统,实现了对数百万个事件的实时处理和通知,同时提高了工作效率和响应速度。
这些成功案例表明,Serverless 编程方式可以帮助企业实现更高效、更灵活、更可靠的应用程序开发和部署,以应对不断变化的业务需求和市场竞争。
Dow Jones 是一家全球知名的新闻和信息服务提供商,它的业务涉及到股票、基金、指数、新闻和信息等多个领域,拥有大量的数据和内容资源。为了更好地利用这些资源,Dow Jones 决定采用 Serverless 编程方式,以构建其内部的图像处理系统。
Dow Jones 的图像处理系统主要用于自动化处理和管理其海量的图片资源,包括图片上传、转码、缩放、剪裁、水印等功能。为了实现这些功能,Dow Jones 选择了 AWS Lambda 和 Amazon S3 作为主要的 Serverless 平台和存储服务,同时采用了其他 AWS 服务如 CloudFormation、CloudWatch、SNS 等来实现整个系统的自动化管理和监控。
在 Dow Jones 的图像处理系统中,每个图片上传时,都会触发一个 AWS Lambda 函数来执行相应的处理逻辑。Lambda 函数会自动从 Amazon S3 存储桶中读取上传的图片,并将其转码、缩放、剪裁等处理,最后保存到另一个 Amazon S3 存储桶中,并发送通知到 SNS 主题,以便后续的其他处理。
采用 Serverless 编程方式后,Dow Jones 可以更快速、更高效地处理和管理其图片资源,同时大幅降低了成本和复杂度。相比传统的服务器架构,Serverless 方式可以实现更好的弹性伸缩、更稳定的性能和可用性,使 Dow Jones 能够更专注于业务的开发和创新。此外,Dow Jones 的图像处理系统还能够自动适应不同的图片格式和分辨率,并能够在多个区域和数据中心之间实现自动化的同步和备份,以满足不同用户的需求和要求。
有了Serverless 编程方式之后, java开发工程师是如何进行开发的
对于 Java 开发工程师来说,在使用 Serverless 编程方式时,可以采用以下步骤进行开发:
首先,需要选择合适的 Serverless 平台和服务提供商,并进行注册和配置。当前市场上较为流行的 Serverless 平台有 AWS Lambda、Azure Functions、Google Cloud Functions 等,每个平台都有其独特的优缺点和适用场景,需要根据具体需求进行选择。
接着,需要创建一个函数项目,并编写相应的函数代码和配置文件。函数项目可以使用常用的 Java 开发工具和框架进行开发,如 Eclipse、IntelliJ IDEA、Spring Boot、Maven 等。函数代码可以采用 Java 8 及以上版本,并使用相应的 Serverless SDK 或 API 进行开发和测试。
在编写函数代码时,需要注意以下几点:首先,需要将代码封装为一个单独的函数或方法,以便在触发器被触发时自动执行。其次,需要确保函数代码具有良好的可读性、可维护性和可测试性,以便后续的维护和升级。最后,需要遵循 Serverless 平台的规范和要求,如函数执行时间、内存限制、触发器配置等,以便最大限度地利用资源和服务。
在完成函数代码和配置文件的编写后,需要进行本地测试和部署。本地测试可以使用常用的单元测试框架进行测试,并确保函数代码和业务逻辑的正确性和健壮性。部署可以使用 Serverless 平台提供的命令行工具、控制台界面或 API 进行部署,并根据实际情况进行配置和优化。
最后,需要进行监控和管理,以便及时发现和处理运行时问题和异常。监控可以使用 Serverless 平台提供的日志、指标、警报等工具进行监控,并及时处理异常情况。管理可以使用 Serverless 平台提供的自动化运维工具和服务进行管理,并保证应用程序的可用性和稳定性。
在使用 AWS Lambda 和 Spring Boot 框架进行开发时,可以使用 AWS Lambda Java 库来进行开发和部署。AWS Lambda Java 库是 AWS 为 Java 开发者提供的一套开发工具和 API,可以方便地在 Spring Boot 框架下进行 Serverless 应用程序的开发和部署。以下是使用 AWS Lambda Java 库进行开发和部署的步骤:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.1</version>
</dependency>
package com.example.demo;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class LambdaFunctionHandler implements RequestHandler<String, String> {
@Override
public String handleRequest(String input, Context context) {
context.getLogger().log("Input: " + input);
// TODO: Business logic implementation
return "Hello from Lambda!";
}
}
启动类
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
<build>
<plugins>
<plugin>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.1</version>
<configuration>
<functionName>hello-world</functionName>
<handler>com.example.demo.LambdaFunctionHandler</handler>
<role>arn:aws:iam::123456789012:role/lambda-role</role>
<description>Hello world function.</description>
<memorySize>512</memorySize>
<timeout>10</timeout>
<region>us-west-2</region>
<runtime>java8</runtime>
<environmentVariables>
<name>ENVIRONMENT</name>
<value>production</value>
</environmentVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>deploy-function</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<build>
<plugins>
<plugin>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.1</version>
<configuration>
<functionName>hello-world</functionName>
<handler>com.example.demo.LambdaFunctionHandler</handler>
<role>arn:aws:iam::123456789012:role/lambda-role</role>
<description>Hello world function.</description>
<memorySize>512</memorySize>
<timeout>10</timeout>
<region>us-west-2</region>
<runtime>java8</runtime>
<environmentVariables>
<name>ENVIRONMENT</name>
<value>production</value>
</environmentVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>deploy-function</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
package com.example.demo;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class LambdaFunctionHandler implements RequestHandler<String, String> {
@Override
public String handleRequest(String input, Context context) {
context.getLogger().log("Input: " + input);
// TODO: Business logic implementation
context.getLogger().log("Output: " + "Hello from Lambda!");
// Write logs to CloudWatch
context.getLogger().log("Custom log message to CloudWatch");
// Publish metrics to CloudWatch
context.getMetricsLogger().incrementCounter("CustomCounter", 1);
return "Hello from Lambda!";
}
}
上述代码中,在函数执行过程中,使用 Context 对象获取 Logger 和 MetricsLogger 对象,并使用相应的方法记录日志和指标信息。这些信息可以自动记录到 AWS Lambda 的 CloudWatch 日志和指标中,可以在控制台界面或 API 中进行查看和分析。
总的来说,使用 AWS Lambda 和 Spring Boot 框架进行 Serverless 应用程序的开发,需要使用 AWS Lambda Java 库提供的 Lambda 函数接口、注解和配置类进行封装和执行,并使用 AWS Lambda 提供的 CloudWatch 日志和指标工具进行监控和管理,以便及时发现和处理运行时问题和异常。
部署在Serverless云服务商的服务, 我们要怎么访问呢?
当将 Spring Boot Web 应用程序部署到 Serverless 平台上时,可以使用 API Gateway 来将 HTTP 请求路由到相应的 Lambda 函数上。API Gateway 是 AWS Lambda 提供的一种托管服务,可将 HTTP 请求转换为 Lambda 函数调用,从而使您的函数能够作为 RESTful API 服务公开。
以下是使用 API Gateway 访问 Serverless 应用程序的一些步骤:
在 AWS Lambda 控制台上创建一个 Lambda 函数,并使用 Spring Boot 和 AWS Lambda Java 库进行开发和部署。
在 AWS API Gateway 控制台上创建一个 API,并将其配置为使用 Lambda 集成。
将 API Gateway 的 URL 配置为公共网关,并将其与您的域名进行映射。API Gateway 可以为您提供默认的 URL,也可以使用您自己的自定义域名。如果您要使用自定义域名,请在 Route 53 上进行配置。
使用 API Gateway 的 URL 来访问您的 Serverless 应用程序。您可以使用 HTTP GET、POST 等请求方法来访问不同的 API 端点。API Gateway 还可以提供验证、授权、缓存、限速等功能,以确保安全和可靠的访问。
总的来说,使用 API Gateway 来访问 Serverless 应用程序,需要在 AWS Lambda 和 API Gateway 上分别进行配置和部署,并将其映射到您的域名上。API Gateway 还提供了许多其他功能和选项,可根据实际需求进行配置和优化,以便最大限度地利用 Serverless 平台的优势和特点。
总的来说,Serverless 编程方式可以让 Java 开发工程师更加专注于业务逻辑和应用程序开发,而不用关心底层服务器的管理和运维,提高了开发效率和应用程序质量。同时,需要注意 Serverless 平台的规范和要求,以便最大限度地利用资源和服务,提高应用程序的性能和可靠性。
Serverless 提供了一种简单、快速、高效的云计算服务模式,可以让开发者更专注于业务逻辑的开发,而不需要关心底层服务器和运维问题。Serverless 的编程方式以事件驱动为核心,可以灵活地应对各种场景和需求。
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
我创建了一个由于“在运行时执行的单例元类定义”而无法编码的对象(这段代码的描述是否正确?)。这是通过以下代码执行的:#defineclassXthatmyusesingletonclassmetaprogrammingfeatures#throughcallofmethod:break_marshalling!classXdefbreak_marshalling!meta_class=class我该怎么做才能使对象编码正确?是否可以从对象instance_of_x的classX中“移除”单例组件?我真的需要一个建议,因为我们的一些对象需要通过Marshal.dump序列化机制进行缓存。
我正在查看Ruby日志记录库Logging.logger方法并从sourceatgithub提出问题与这段代码有关:logger=::Logging::Logger.new(name)logger.add_appendersappenderlogger.additive=falseclass我知道类 最佳答案 这实际上删除了方法(当它实际被执行时)。这是确保close不会被调用两次的保障措施。看起来好像有嵌套的“class 关于Ruby元编程问题,我们在StackOverflow上找到一
使用Paperclip,我想从这样的URL抓取图像:require'open-uri'user.photo=open(url)问题是我最后得到一个像“open-uri20110915-4852-1o7k5uw”这样的文件名。有什么方法可以更改user.photo上的文件名?作为一个额外的变化,Paperclip将我的文件存储在S3上,所以如果我可以在初始分配中设置我想要的文件名就更好了,这样图像就会上传到正确的S3key。像这样:user.photo=open(url),:filename=>URI.parse(url).path 最佳答案
我正在开发一个xcode自动构建系统。在执行一些预构建验证时,我想检查指定的证书文件是否已被撤销。我了解securityverify-cert验证其他证书属性但不验证吊销。我如何检查撤销?我正在用Ruby编写构建系统,但我对任何语言的想法都持开放态度。我阅读了这个答案(Openssl-Howtocheckifacertificateisrevokedornot),但指向底部的链接(DoesOpenSSLautomaticallyhandleCRLs(CertificateRevocationLists)now?)进入的Material对我的目的来说有点过于复杂(用户上传已撤销的证书是一
关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭11年前。Improvethisquestion我不经常使用ruby-通常它加起来相当于每两个月或更长时间编写一次脚本。我的大部分编程都是使用C++进行的,这与ruby有很大不同。由于我与ruby之间的差距如此之大,我总是忘记语言的基本方面(比如解析文本文件和其他简单的东西)。我想每天练习一些基本的东西,我想知道是否有一些我可以订阅的网站,并且会向我发送当天的Ruby问题或类似的东西。有人知道这样的站点/Internet服务吗?
我一直在寻找一种以编程方式或通过命令行将mp3转换为aac的方法,但没有成功。理想情况下,我有一段代码可以从我的Rails应用程序中调用,将mp3转换为aac。我安装了ffmpeg和libfaac,并能够使用以下命令创建aac文件:ffmpeg-itest.mp3-acodeclibfaac-ab163840dest.aac当我将输出文件的名称更改为dest.m4a时,它无法在iTunes中播放。谢谢! 最佳答案 FFmpeg提供AAC编码功能(如果您已编译它们)。如果您使用的是Windows,则可以从here获取完整的二进制文件。
我想输入一个字符串并返回一个可用于描述字符串结构的正则表达式。正则表达式将用于查找更多与第一个结构相同的字符串。这是故意模棱两可的,因为我肯定会漏掉SO社区中的某个人会发现的情况。请发布任何和所有可能的方法来做到这一点。 最佳答案 简单的答案(可能不是您想要的)是:返回输入字符串(正则表达式特殊字符转义)。这始终是与字符串匹配的正则表达式。如果您希望识别某些结构,则必须提供有关您希望识别的结构类型的更多信息。如果没有这些信息,问题就会以模棱两可的方式陈述,并且有许多可能的解决方案。例如,输入字符串'aba'可以描述为'阿巴''阿巴*