超快微服务:当Microstream遇上Wildfly

480 篇文章 9 订阅
480 篇文章 2 订阅
本文探讨了如何结合Microstream和Wildfly创建高性能微服务应用。MicroProfile优化了企业版Java以适应微服务架构,而Wildfly作为一个强大的应用服务器,助力构建高效应用。通过Microstream,实现了微秒级查询时间和低延迟数据访问,增强了数据持久化的效率。通过示例展示了如何创建一个使用Microstream和MicroProfile的CRUD REST API,强调了这两者的集成为微服务带来超快运行速度。
摘要由CSDN通过智能技术生成

当我们谈论创建可扩展的应用程序时,微服务已成为一个流行语。但这足够了吗?答案是否定的,与任何软件架构决策一样,它也有一个权衡和几个挑战。对于我们Java开发人员来说,这两种工具的组合使我们的工作更轻松:Microstream和MicroProfile。本文将介绍如何结合Microstream和 Wildfly 来创建一个性能稳定且速度极快的微服务应用程序。

使用 Wildfly 的微服务

作为面对分布式系统的第一步,微服务为软件工程师带来了挑战。在Java世界中,有几种工具可以使我们的生活更轻松,尤其是MicroProfile。

MicroProfile 的目标是针对微服务架构优化企业版Java。它基于Java EE / Jakarta EE标准以及专门用于微服务的API,例如REST Client、 Configuration、 Open API等。

Wildfly是一个功能强大,模块化和轻量级的应用程序服务器,可帮助你构建令人惊叹的应用程序。

使用Microstream实现数据持久化速度

当我们谈论微服务时,我们谈论的是分布式系统及其带来的挑战,这在持久性层中也是一样的。

不幸的是,我们没有足够的文章来谈论它。当你对业务有很多不确定的信息时,我们应该有一个模型,甚至是无模式数据库。尽管如此,持久性层仍然存在很多问题,主要是因为它难以更改。

制作可扩展应用程序的秘诀之一是无状态,但我们在持久性层中负担不起它。首先,数据库旨在保存信息及其状态。

使数据持久化层更高效的解决方案之一是直接与 Java 实体集成为图表,这就是Microstream所做的。

Microstream使用纯Java实现了超快速的内存数据处理。它提供微秒级查询时间、低延迟数据访问、巨大的数据吞吐量和工作负载。因此,它节省了大量的CPU功率,二氧化碳排放和数据中心的成本。

显示代码

让我们将两者结合起来,制作一个Ultra-Fast Microservices。我们将选择一个简单的演示来展示两者如何结合。在此示例中,我们将创建一个简单的 CRUD,其中包含产品、名称和评级,并将其导出为 REST API。

第一步是创建MicroProfile骨架:它毫不费力且流畅,主要是因为我们可以使用可视化MicroProfile启动器。将 Microprofile 版本 4.1 与 Java 11 和 Wildfly 一起设置,如下图所示:

我们已有了应用程序的骨架。下一步是添加Microstream并使两者协同工作。幸运的是,有一个库可以通过CDI扩展集成两者。因此,借助此API,任何具有CDI和MicroProfile Config的应用程序都可以工作。

1.<dependency>  
2.     <groupId>one.microstream</groupId>  
3.     <artifactId>microstream-integrations-cdi</artifactId>  
4.     <version>LAST_VERSION_HERE</version>  
5. </dependency>  

框架已设置,让我们从代码开始。模型是中心部分。它是一个平滑的示例,我们将创建一个包含几个字段的产品实体。使用Microstream的主要建议是使用不可变实体。因此,我们将创建一个产品作为不可变实体。

1.public class Product {  
2.    private final long id;  
3.    private final String name;  
4.    private final String description;  
5.    private final int rating;  
6.  
7.    @JsonbCreator  
8.    public Product(  
9.            @JsonbProperty("id") final long id,  
10.            @JsonbProperty("name") final String name,  
11.            @JsonbProperty("description") final String description,  
12.            @JsonbProperty("rating") final int rating){  
13.            //...  
14.            }  
15.  
16.} 

JSON注释只告知MicroProfile如何将实体序列化为JSON。下一步是定义产品集合,我们称之为库存。库存类是具有多种操作方法的一组产品。此类是实体与Microstream引擎之间的链接。与Microstream 的连接将使用Storage 注解。

1.import java.util.Collections;  
2.import java.util.HashSet;  
3.import java.util.Objects;  
4.import java.util.Optional;  
5.import java.util.Set;  
6.import java.util.function.Predicate;  
7.  
8.import one.microstream.integrations.cdi.types.Storage;  
9.  
10.  
11.@Storage  
12.public class Inventory {  
13.    private final Set<Product> products = new HashSet<>();  
14.  
15.    public void add(final Product product) {  
16.        Objects.requireNonNull(product, "product is required");  
17.        this.products.add(product);  
18.    }  
19.  
20.    public Set<Product> getProducts() {  
21.        return Collections.unmodifiableSet(this.products);  
22.    }  
23.  
24.    public Optional<Product> findById(final long id) {  
25.        return this.products.stream().filter(this.isIdEquals(id)).limit(1).findFirst();  
26.    }  
27.  
28.    public void deleteById(final long id) {  
29.        this.products.removeIf(this.isIdEquals(id));  
30.  
31.    }  
32.  
33.    private Predicate<Product> isIdEquals(final long id) {  
34.        return p -> p.getId() == id;  
35.    }  
36.  
37.  @Override  
38.  public boolean equals(Object o) {  
39.    if (this == o) return true;  
40.    if (o == null || getClass() != o.getClass()) return false;  
41.    Inventory inventory = (Inventory) o;  
42.    return Objects.equals(products, inventory.products);  
43.  }  
44.  
45.  @Override  
46.  public int hashCode() {  
47.    return Objects.hash(products);  
48.  }  
49.  
50.  @Override  
51.  public String toString() {  
52.    return "Inventory{" +  
53.        "products=" + products +  
54.        '}';  
55.  }  
56.}  

集合准备就绪后,让我们创建存储库。要使用我们的 Inventory 类,我们可以使用 CDI 中的 Inject 注释。我们需要将此操作提交到将要更改此集合的每个操作。对于任何可以更改清单的方法,都有Store注解为我们自动处理它。

1.public interface ProductRepository  
2.{  
3.  Collection<Product> getAll();  
4.    
5.  Product save(Product item);  
6.    
7.  Optional<Product> findById(long id);  
8.    
9.  void deleteById(long id);  
10.}  
11.  
12.  
13.@ApplicationScoped  
14.public class ProductRepositoryStorage implements ProductRepository {  
15.    private static final Logger LOGGER = Logger.getLogger(ProductRepositoryStorage.class.getName());  
16.  
17.    @Inject  
18.    private Inventory inventory;  
19.    
20.    @Override  
21.    public Collection<Product> getAll() {  
22.        return this.inventory.getProducts();  
23.    }  
24.  
25.    @Override  
26.    @Store  
27.    public Product save(final Product item) {  
28.        this.inventory.add(item);  
29.        return item;  
30.    }  
31.  
32.    @Override  
33.    public Optional<Product> findById(final long id) {  
34.        LOGGER.info("Finding the item by id: " + id);  
35.        return this.inventory.findById(id);  
36.    }  
37.  
38.    @Override  
39.    @Store  
40.    public void deleteById(final long id) {  
41.        this.inventory.deleteById(id);  
42.    }  
43.}  

最后一步是将此产品公开为 Rest API。然后,我们将使用Jakarta EE API返回MicroProfile:JAX-RS。接下来,我们将使用 MicroProfile 创建 Open API 文档。

1.@RequestScoped  
2.@Path("products")  
3.@Consumes(MediaType.APPLICATION_JSON)  
4.@Produces(MediaType.APPLICATION_JSON)  
5.public class ProductController  
6.{  
7.  @Inject  
8.  private ProductRepository repository;  
9.    
10.  // TODO don't worried about pagination  
11.  @GET  
12.   public Collection<Product> getAll()  
13.  {  
14.    return this.repository.getAll();  
15.  }  
16.    
17.  @GET  
18.  @Path("{id}")  
19.  @Operation(summary = "Find a product by id", description = "Find a product by id")  
20.   public Product findById(@PathParam("id") final long id)  
21.  {  
22.    return this.repository.findById(id).orElseThrow(  
23.      () -> new WebApplicationException("There is no product with the id " + id, Response.Status.NOT_FOUND));  
24.  }  
25.    
26.  @POST  
27.  public Response insert(final Product product)  
28.  {  
29.    return Response.status(Response.Status.CREATED).entity(this.repository.save(product)).build();  
30.  }  
31.    
32.  @DELETE  
33.  @Path("{id}")  
34.   public Response delete(@PathParam("id") final long id){  
35.    this.repository.deleteById(id);  
36.    return Response.status(Response.Status.NO_CONTENT).build();  
37.  }  
38.    
39.}  

就是这样!我们可以测试运行的应用程序并检查结果。

1.mvn clean package  
2.java -jar target/wildfly-example-bootable.jar  
3.  
4.curl --location --request POST 'http://localhost:8080/products/' \  
5.--header 'Content-Type: application/json' \  
6.--data-raw '{"id": 1, "name": "banana", "description": "a fruit", "rating": 5}'  
7.  
8.curl --location --request POST 'http://localhost:8080/products/' \  
9.--header 'Content-Type: application/json' \  
10.--data-raw '{"id": 2, "name": "watermelon", "description": "watermelon sugar ahh", "rating": 4}'  

我们最终在Wildfly和Microstream之间实现了集成。本教程展示了两者如何协同工作,并为你提供了一种应对持久性问题的新工具:Microstream。事实上,当你想要创建微服务来超快地运行它时,Microstream和Wildfly是很好的盟友。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值