在上一篇文章中,我们使用SpringBoot和Docker创建了第一个微服务“ ProductService”。 在这一部分中,我们将详细介绍如何使用Spring Cloud,netflix库,API网关来管理多个微服务。

假设对于我们的订单管理系统,最小关系可能是这样的:

因此,让我们以构建“ productService”的类似方式再构建两个名为“ orderService”和“ customerService”的服务。

订购服务

要创建订单,我们可以传递customerId,以及带有productId和数量的项目列表。 让我们看看如何做到这一点:

@PostMapping("/orders")public Order save(@RequestBody CustomerOrderRequest request) {return orderRepository.save(Order.builder().customerId(request.getCustomerId()).externalReference(request.getExternalReference()).items(toItems(request.getItems())).build());}private List toItems(List items) {return items.stream().map(item -> Item.builder().productId(item.getProductId()).quantity(item.getQuantity()).build()).collect(Collectors.toList());}

在这里,我们将customerId和带有productIds的项目列表保存到数据库中。

为了获取完整的订单明细,我们需要完整的客户对象和产品明细。 结果看起来像这样:

{"orderId": "1234","externalReference": "234257hf","customer": {"id": 123,"firstName": "anirudh","lastName": "bhatnagar","phone": "21323","email": "test@test.com","address": {"addressLine1": "123","addressLine2": "pwe","city": "Syd","state": "NSW","country": "Aus","postcode": 2000}},"createdDate": "2018-11-12","items": [{"product": {"id": 123,"name": "Nike Shoes","description": "Mens shoes","price": "100","sku": "1234"},"quantity": 3}],"totalOrderCost": "300.00","totalOrderTax": "30.00"
}

详细的订单响应应包含客户,地址,产品和订单总成本的详细信息。 为了获取此信息,订购服务将需要从产品服务和客户服务获取详细信息。

从Order Service中的ProductService获取产品详细信息
为了获取Order Service中的产品服务详细信息,我们需要一个正在运行的产品服务,以及一个orderController客户端,以对ProductService进行http GET调用。 对于httpClient,我们将使用Netflix提供的OpenFeign客户端库,它可以作为spring-cloud starter的一部分使用,因此让我们在build.gradle文件中添加该依赖项:

implementation('org.springframework.cloud:spring-cloud-starter-openfeign')
dependencyManagement {imports {mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"}
}

现在,我们已经添加了依赖项,我们将使用@FeignClient为此服务创建一个名为“ ProductServiceProxy”的代理接口:

@FeignClient(name = "product-service", url = "localhost:8001")
public interface ProductServiceProxy {@GetMapping("/products/{id}")Product getProduct(@PathVariable("id") Long id);
}

我们已经在界面中添加了注释@FeignClient,并配置了产品服务的名称和URL。
我们还需要通过在主类中添加另一个注释来为我们的应用程序启用Feign客户端:

@SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication {
......

最后,我们需要调用在本地主机端口8001上运行的产品服务,以使用订单中提供的产品ID获取产品详细信息,并填充订单详细信息响应对象:

@GetMapping("/orders/{id}")public CustomerOrderDetails getOrders(@PathVariable("id") Long orderId) {final Order order = orderRepository.findById(orderId).orElse(null);if (order == null) {return null;}return toCustomerOrderDetails(order);}private CustomerOrderDetails toCustomerOrderDetails(Order order) {return CustomerOrderDetails.builder().orderId(order.getId()).createdDate(order.getCreatedDate()).externalReference(order.getExternalReference()).items(toItemList(order.getItems())).build();}private List<com.anirudhbhatnagar.orderService.dto.product.Item> toItemList(List<Item> items) {return items.stream().map(item -> toItemDto(item)).collect(Collectors.toList());}private com.anirudhbhatnagar.orderService.dto.product.Item toItemDto(Item item) {return com.anirudhbhatnagar.orderService.dto.product.Item.builder().product(productServiceProxy.getProduct(item.getProductId())).build();}

如果您仔细看一下上面的代码,

productServiceProxy.getProduct(item.getProductId())

您将看到,一旦获得获取获取给定orderId的订单详细信息的请求,我们首先将获取保存在订单服务数据库中的订单数据,然后使用每个项目或订单中提供的productId,我们将调用productService并填充orderDetails响应对象。

测试一下
一旦orderService启动并在端口8002上运行并且productService在端口8001上运行。我们可以测试我们的应用程序:确保有一些使用产品服务创建的产品,如先前的博客所述 。
记下您在产品服务中创建的productId,并使用相同的代码创建新订单:使用邮递员在http:// localhost:8002 / orders上进行POST,请求如下:

{
"customerId" : "123",
"externalReference" : "1234567",
"items" : [{"productId" : 1,"quantity" : 2
}]
}

这将创建一个新订单,而不是在响应中查找订单ID。 现在,使用以下订单ID获取订单详细信息:在http:// localhost / 8002 / orders / {order-id}上执行GET,这将返回以下响应:

{"orderId": 12,"externalReference": "1234567","customer": null,"createdDate": null,"items": [{"product": {"id": "1","name": "Nike","description": "Shoes","price": "100","sku": "1234"},"quantity": 2}],"totalOrderCost": "200"
}

因此,在这里我们看到了订单服务如何向产品服务发出请求并填充响应对象。 但是,我们仍然将客户视为“ null”,因此,为了填充客户详细信息,我们需要从客户服务获取。 为了设置客户服务,我们将执行以下操作:
1.以与我们使用Spring初始化程序进行产品或订单服务类似的方式设置客户服务。
2.在OrderService中设置代理客户端服务 3.从Order Controller调用CustomerService,以在Order Details响应对象内填充客户详细信息。 如果一切正常,我们也应该查看客户详细信息。

当前,我们已经在订单服务中对服务的URL进行了硬编码,但是理想情况下需要动态发现它们。 因此,在下一部分中,我们将为3个微服务添加“服务发现”和“负载平衡”。

整个源代码可以在这里引用。

翻译自: https://www.javacodegeeks.com/2018/11/spring-microservices-docker-kubernetes-2.html

Spring Boot微服务,Docker和Kubernetes研讨会–第2部分相关推荐

  1. Docker容器及Spring Boot微服务应用

    2019独角兽企业重金招聘Python工程师标准>>> Docker容器及Spring Boot微服务应用 1 什么是Docker 1.1 Docker的出现 问题一:项目实施环境复 ...

  2. Docker基础篇 - (六)Docker 网络Spring Boot微服务打包Docker镜像

    ⑦ Docker 网络 7.1 理解Docker0 清空下前面的docker 镜像.容器 # 删除全部容器 [root@cVzhanshi tomcat-diy]# docker rm -f $(do ...

  3. Spring Boot 微服务编码风格指南和最佳实践

    文奇摄于世界尽头州立公园 通过多年来使用 Spring Boot 微服务,我编制了一份编码风格指南和最佳实践列表.这份清单并不全面,但我希望您能找到一两点可以借鉴的地方,无论您是新手还是经验丰富的 S ...

  4. spring boot 微服务集群 + 注册中心

    spring boot 微服务框架下载地址: https://start.spring.io/ 注册中心 Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进 ...

  5. Spring Boot微服务的黑匣子测试是如此简单

    当我需要进行原型设计,概念验证或在空闲时间使用一些新技术时,开始新项目对于Maven来说总是有点烦人. 不得不说,设置Maven项目并不难,您可以使用Maven原型. 但是原型通常是过时的. 谁想玩旧 ...

  6. Spring Boot微服务间文件返回实现

    Feign接口获取文件流问题_Java_wyazyf的博客-CSDN博客 https://blog.csdn.net/wyazyf/article/details/93200033 Spring Bo ...

  7. springboot 微服务_使用 Docker 部署 Spring Boot微服务

    Docker 技术发展为微服务落地提供了更加便利的环境,使用 Docker 部署 Spring Boot 其实非常简单,这篇文章我们就来简单学习下. 首先构建一个简单的 Spring Boot 项目, ...

  8. 高级版的 jvisualvm :Spring Boot Admin 监控 Spring Boot 微服务项目

    前奏:先说一下 Java VisualVM Java VisualVM 是一个能够监控 JVM 的 jdk 自带的图形化工具: 在 $JAVA_HOME/bin 目录下,可直接运行它. 要想监控远程服 ...

  9. Spring Boot微服务,Docker和Kubernetes研讨会–第一部分

    在本系列研讨会中,我们将使用spring boot,docker构建一些微服务,然后将它们部署到kubernetes中. 因此,让我们开始吧. 首先,我们需要定义一个问题陈述. 可以说我们要建立一个订 ...

  10. Spring Boot微服务,Docker和Kubernetes研讨会–第3部分

    在之前的文章中,我们为使用Docker和Spring Boot的订单管理系统构建了一些微服务(订单服务,产品服务,客户服务). 我们使用Netflix库来管理,发现和平衡微服务. 管理这些微服务及其多 ...

最新文章

  1. tesseract3.01的训练和使用
  2. pycharm专业版(window)安装
  3. Flink运行出现Assigned key must not be null
  4. encountered unknown setting 'componentData' for class 'cus.crm.mycalendar.C
  5. Jmeter===Jmeter中使用CSV Data Set Config参数化不重复数据执行N遍(转)
  6. DB排行榜更新,.NET Core+MySQL成主流!
  7. 3.5 RNN 层使用方法
  8. 6.0 增加京东支付
  9. 英语单词拼写游戏开发纪录
  10. 微信小程序-“授权失败”场景的优雅处理
  11. JavaWeb报错500 类错误 解决方法
  12. linux+下数学公式文档,markdown 数学公式
  13. simpson公式matlab实现,数值分析复化梯形公式复化Simpson公式MATLAB程序
  14. echart-pie
  15. LeetCode 581. 最短无序连续子数组 (unfinished 排序+双指针)
  16. 索尼电视投屏声音与画面不同步现象解决方案
  17. css鼠标放上按钮变色
  18. 我国网络安全应急体系
  19. Michael Kors 完成了对 Versace 的收购,集团还正式改名成了 Capri
  20. 如何处理X-Lite和eyeBeam常见软电话故障及方法

热门文章

  1. HDU5322 - cdq分治FFT加速dp
  2. JavaFX滚动事件
  3. IDEA的debug方法头坑
  4. Executor 与 ExecutorService 和 Executors 傻傻分不清
  5. 漫画:什么是时间复杂度
  6. Java开发必须掌握的5种加密策略
  7. Vue.js2.0开发环境搭建(三)
  8. 输入一个字母,转大小写
  9. sql server中创建数据库和表的语法
  10. 《四世同堂》金句摘抄(四)