概述
The new Azure SDK for Java
这篇博客文章使用即将推出的Java Azure SDK:在撰写本文时,它仍是预览版本,但是许多人已经开始使用它。
To be more precise, we are talking here of the Azure SDK for Java (August 2019 Preview), also seen as "1.0.0-preview.2" on Maven Central.
This new release is important as it uses some new, modern API guidelines, and also because its asynchronous features are powered by Spring Reactor.
这些新的响应式API有趣,因为它们提供了更好的可伸缩性,并且可以与Spring很好地协同工作。 不幸的是,它们是以使用一个API的代价为代价的,该API理解起来更加复杂,调试起来也更加复杂:这就是我们撰写此博客文章的原因!
The problem with uploading data
上载数据需要时间,并且通常需要良好的连接:如果您使用的是移动设备,这肯定是一个问题! 如果我们使用基于线程的模型,则意味着发送多个文件将阻塞多个线程,并且伸缩性不会很高。 或者,您可以将所有文件放在自己可以管理的队列中:这可能对代码来说相当复杂,并且这将阻止您并行上传这些文件,因此性能将不会很好。 这就是Spring Reactor发挥作用的地方!
这里的想法是以异步,非阻塞的方式上传数据,因此我们可以并行上传许多文件而不会阻塞系统。
Spring Reactor and Spring Webflux
请注意,这里的示例适用于Spring Webflux:这是Spring的响应版本,由于它的工作方式与经典的Spring MVC(基于线程)完全不同,因此该代码不适用于Spring MVC 。 这是进行反应式编程时的问题之一:混合反应式代码和基于线程的代码实际上是不可能的,因此您的所有项目都需要使用反应式API进行设计和思考。 我认为,这最适合于微服务架构,在该架构中,您将使用反应式API编写某些特定服务,而使用传统的基于线程的API编写某些服务。 响应式微服务的开发和调试可能会稍微复杂一些,但会提供更好的可伸缩性,启动时间,内存消耗,因此它们将用于某些特定的资源密集型任务。
Creating a Storage Account
In the the Azure portal, create a new storage account:
创建完成后,转到该存储帐户并选择“共享访问签名”或SAS。 SAS是一种签名,它允许在有限的时间段内访问某些资源:非常适合在特定位置上载数据而不损害安全性。
单击“生成SAS和连接字符串”后,复制最后生成的文本字段,名称为“ Blob服务SAS URL”。 这是我们将与用于Java的Azure SDK一起使用的版本。
Add the Azure SDK for Java to the pom.xml
由于用于Java的Azure SDK预览位于Maven Central上,因此只需将依赖项添加到项目的pom.xml中即可:
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
<version>12.0.0-preview.2</version>
</dependency>
Using the new asynchronous API
Let's first have a look at the final code, which is available on https://github.com/jdubois/jhipster-azure-blob-storage/blob/master/src/main/java/com/example/demo/PictureResource.java:
@RestController
@RequestMapping("/api")
public class PictureResource {
Logger log = LoggerFactory.getLogger(PictureResource.class);
@Value("${AZURE_BLOB_ENDPOINT}")
private String endpoint;
@PostMapping("/picture")
public void uploadPicture() throws IOException {
log.debug("Configuring storage client");
BlobServiceAsyncClient client =
new BlobServiceClientBuilder()
.endpoint(endpoint)
.buildAsyncClient();
client.createContainer("pictures")
.doOnError((e) -> {
log.info("Container already exists");
})
.flatMap(
(clientResponse) -> {
log.info("Uploading picture");
return clientResponse
.value()
.getBlockBlobAsyncClient("picture.png")
.uploadFromFile("src/main/resources/image.png");
})
.subscribe();
}
}
警告该API仅在使用Spring Reactive时有效,因此请注意,您需要在Spring Webflux项目中使用它,而不是Spring MVC项目中。
验证是使用我们上面复制的“ Blob服务SAS URL”完成的,并且使用AZURE_BLOB_ENDPOINT此示例中的环境变量:请注意,URL中包含SAS,因此不需要在其他地方进行身份验证(证书()API中的方法,这可能会产生误导,但对我们而言是无用的)。 因此,该URL应该安全地存储,并且不要与您的代码一起提交。
使用Spring Reactor API发送图像:
- 我们创建一个特定的图片用于存储一些数据的容器然后,我们使用Spring Reactor的API上传图片最后,我们使用订阅()方法,使我们的代码异步运行
结果,此方法将很快返回,然后将在另一个线程中创建容器并上传图像。 这会使调试变得更加困难,但允许我们的应用程序接受更多请求,并以异步方式处理它们。
Improving the reactive code
This tip was provided by Christophe Bornet, many thanks to him!
前面的代码是我们通常在项目中看到的,但是为了使Spring Webflux处理。订阅()部分:这将保留Spring Webflux和Azure SDK之间的背压。 同样,这意味着错误将由Spring Webflux管理,而不是丢失:如果使用Azure SDK上传文件时发生错误,则使用此新代码将产生500个错误。
The change can be seen in this commit, where we replace the .subscribe()
by a .then()
and we return a Mono<Void>
instead of not returning anything. It will be Spring Webflux's responsibility to handle that Mono
and call .subscribe()
.
结果代码如下:
@PostMapping("/picture")
public Mono<Void> uploadPicture() throws IOException {
log.debug("Configuring storage client");
BlobServiceAsyncClient client =
new BlobServiceClientBuilder()
.endpoint(endpoint)
.buildAsyncClient();
return client.createContainer("pictures")
.doOnError((e) -> {
log.info("Container already exists");
})
.flatMap(
(clientResponse) -> {
log.info("Uploading picture");
return clientResponse
.value()
.getBlockBlobAsyncClient("picture.png")
.uploadFromFile("src/main/resources/image.png");
})
.then();
}
它是反应式API的更高级用法,但结果值得付出麻烦。
Conclusion and feedback
当前,我们缺少有关适用于Java的Azure SDK中此新异步API的文档和示例。 我认为这在某些特定情况下非常重要,例如我们在这里遇到的情况,因为如果您要可伸缩的应用程序,通常不应在当前线程中上载或下载数据。
该SDK仍处于预览状态,因此,如果您对此API有任何反馈,请对此文章发表评论!
例如,当前的API允许您创建一个容器(如果容器已经存在,则将失败)或获取现有容器(如果容器尚不存在,则将失败)。 您是否认为应该有类似的选择getOrCreateContainer(“ name”),如果需要,它将自动创建一个容器?
from: https://dev.to//azure/using-the-new-azure-sdk-for-java-to-upload-images-asynchronously-using-spring-reactor-20ha
最后
以上就是呆萌蚂蚁为你收集整理的使用Spring Reactor使用新的Java版Azure SDK异步上传图像的全部内容,希望文章能够帮你解决使用Spring Reactor使用新的Java版Azure SDK异步上传图像所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复