基于customerId来实现

配置Kong负载均衡器管理SpringBoot应用实例
该文详细描述了如何在192.168.19.50上部署多个SpringBoot应用实例,并通过Kong创建两个上游(cn_upstream和ot_upstream),将请求路由到不同的服务。每个上游对应不同端口的应用,然后创建服务(cn_service和ot_service)并将它们与上游关联,最后配置路由和测试访问。此外,还展示了启用ACL插件的示例。

定义两个upstream,他们和service及route的关系如下:
在这里插入图片描述
这里我们使用

0、将下面的这个spring boot项目在192.168.19.50上进行部署

KongDemoApplication.java

package com.example.kongdemo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class KongDemoApplication {
    @Value("${server.port}")
    private String port;

    @Value("${spring.range}")
    private String range;

    public static void main(String[] args) {
        SpringApplication.run(KongDemoApplication.class, args);
    }

    @GetMapping("/hello")
    public String hello(){
        return "hello : " + port + ";range:" + range;
    }

    @GetMapping("/hello/sub")
    public String subHello(){
        return "sub-hello: " + port + ";range:" + range;
    }

}

applicaton.properties

server.port=8080
spring.range=CN

项目打成jar包后,在192.168.19.50机器按照如下命令运行6个实例:
nohup java -jar kong-demo-0.0.1-SNAPSHOT.jar --server.port=8080 --spring.range=CN > 8080.txt &
nohup java -jar kong-demo-0.0.1-SNAPSHOT.jar --server.port=8081 --spring.range=CN > 8081.txt &
nohup java -jar kong-demo-0.0.1-SNAPSHOT.jar --server.port=8082 --spring.range=CN > 8082.txt &
nohup java -jar kong-demo-0.0.1-SNAPSHOT.jar --server.port=8083 --spring.range=OT > 8083.txt &
nohup java -jar kong-demo-0.0.1-SNAPSHOT.jar --server.port=8084 --spring.range=OT > 8084.txt &
nohup java -jar kong-demo-0.0.1-SNAPSHOT.jar --server.port=8085 --spring.range=OT > 8085.txt &

1、创建cn_upstream及ot_upstream

1.1 创建cn_upstream

[root@min ~]# curl -X POST http://localhost:8001/upstreams \
   --data name=cn_upstream
{"hash_fallback":"none","hash_fallback_header":null,"hash_fallback_query_arg":null,"hash_fallback_uri_capture":null,"host_header":null,"tags":null,"updated_at":1685570147,"name":"cn_upstream","hash_on":"none","hash_on_header":null,"client_certificate":null,"hash_on_query_arg":null,"hash_on_uri_capture":null,"use_srv_name":false,"slots":10000,"hash_on_cookie":null,"hash_on_cookie_path":"/","healthchecks":{"active":{"healthy":{"interval":0,"successes":0,"http_statuses":[200,302]},"unhealthy":{"interval":0,"http_failures":0,"timeouts":0,"http_statuses":[429,404,500,501,502,503,504,505],"tcp_failures":0},"http_path":"/","https_sni":null,"type":"http","concurrency":10,"https_verify_certificate":true,"headers":null,"timeout":1},"threshold":0,"passive":{"healthy":{"successes":0,"http_statuses":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308]},"unhealthy":{"timeouts":0,"http_failures":0,"http_statuses":[429,500,503],"tcp_failures":0},"type":"http"}},"id":"5aae2f66-3fb5-461d-9189-e30fa80a2d61","algorithm":"round-robin","created_at":1685570147}

1.2 创建ot_upstream

[root@min ~]# curl -X POST http://localhost:8001/upstreams   --data name=ot_upstream
{"hash_fallback":"none","hash_fallback_header":null,"hash_fallback_query_arg":null,"hash_fallback_uri_capture":null,"host_header":null,"tags":null,"updated_at":1685570784,"name":"ot_upstream","hash_on":"none","hash_on_header":null,"client_certificate":null,"hash_on_query_arg":null,"hash_on_uri_capture":null,"use_srv_name":false,"slots":10000,"hash_on_cookie":null,"hash_on_cookie_path":"/","healthchecks":{"active":{"healthy":{"interval":0,"successes":0,"http_statuses":[200,302]},"unhealthy":{"interval":0,"http_failures":0,"timeouts":0,"http_statuses":[429,404,500,501,502,503,504,505],"tcp_failures":0},"http_path":"/","https_sni":null,"type":"http","concurrency":10,"https_verify_certificate":true,"headers":null,"timeout":1},"threshold":0,"passive":{"healthy":{"successes":0,"http_statuses":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308]},"unhealthy":{"timeouts":0,"http_failures":0,"http_statuses":[429,500,503],"tcp_failures":0},"type":"http"}},"id":"918d9fec-c274-48df-880d-d522aa0b7482","algorithm":"round-robin","created_at":1685570784}

2、为cn_upstream、ot_upstream添加target

2.1、为cn_upstream添加target

curl -X POST http://localhost:8001/upstreams/cn_upstream/targets \
  --data target='192.168.19.50:8080'
curl -X POST http://localhost:8001/upstreams/cn_upstream/targets \
  --data target='192.168.19.50:8081'
  curl -X POST http://localhost:8001/upstreams/cn_upstream/targets \
  --data target='192.168.19.50:8082'

在这里插入图片描述

2.2、为op_upstream添加target

curl -X POST http://localhost:8001/upstreams/ot_upstream/targets \
  --data target='192.168.19.50:8083'
curl -X POST http://localhost:8001/upstreams/ot_upstream/targets \
  --data target='192.168.19.50:8084'
  curl -X POST http://localhost:8001/upstreams/ot_upstream/targets \
  --data target='192.168.19.50:8085'

3、创建service

3.1、创建cn_service

创建cn_service,并将其host指向cn_upstream

[root@min ~]# curl -i -s -X POST http://localhost:8001/services \
  --data name=cn_service \
  --data host='cn_upstream'
HTTP/1.1 201 Created
Date: Wed, 31 May 2023 22:10:00 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: http://localhost:8002
X-Kong-Admin-Request-ID: sUQcvdGQ4m002ZnQysRNnFaEydvU0edv
vary: Origin
Access-Control-Allow-Credentials: true
Content-Length: 371
X-Kong-Admin-Latency: 9
Server: kong/3.3.0.0-enterprise-edition

{"connect_timeout":60000,"read_timeout":60000,"protocol":"http","host":"cn_upstream","updated_at":1685571000,"name":"cn_service","retries":5,"write_timeout":60000,"id":"39e44a6e-dfdf-4a32-85ba-db003f424073","tls_verify":null,"port":80,"tls_verify_depth":null,"enabled":true,"client_certificate":null,"path":null,"ca_certificates":null,"created_at":1685571000,"tags":null}

在这里插入图片描述

3.1、创建ot_service

创建ot_service,并将其host指向ot_upstream

 curl -i -s -X POST http://localhost:8001/services \
  --data name=ot_service \
  --data host='ot_upstream'

在这里插入图片描述

4、为cn_service和ot_service创建route

4.1、为cn_service创建route,path为:/cn_service

curl -i -X POST http://localhost:8001/services/cn_service/routes \
  --data 'paths[]=/cn_service' \
  --data name=cn_route

在这里插入图片描述

4.1、为cn_service创建route,path为:/cn_service

curl -i -X POST http://localhost:8001/services/ot_service/routes \
  --data 'paths[]=/ot_service' \
  --data name=ot_route

在这里插入图片描述

5、测试的搭建情况

如果访问192.168.19.50:8000/cn_service/hello将会被代理到cn_upstream上,即会被192.168.19.50:8080/hello、192.168.19.50:8081/hello、192.168.19.50:8082/hello三个服务中的一个处理

如果访问192.168.19.50:8000/ot_service/hello将会被代理到cn_upstream上,即会被192.168.19.50:8083/hello、192.168.19.50:8084/hello、192.168.19.50:8085/hello三个服务中的一个处理

[root@min ~]# curl http://192.168.19.50:8000/cn_service/hello
hello : 8082;range:CN[root@min ~]# curl http://192.168.19.50:8000/cn_service/hello
hello : 8080;range:CN[root@min ~]# curl http://192.168.19.50:8000/cn_service/hello
hello : 8080;range:CN[root@min ~]# curl http://192.168.19.50:8000/cn_service/hello
hello : 8081;range:CN[root@min ~]# curl http://192.168.19.50:8000/cn_service/hello
hello : 8082;range:CN[root@min ~]# 

[root@min ~]# curl http://192.168.19.50:8000/ot_service/hello
hello : 8085;range:OT[root@min ~]# curl http://192.168.19.50:8000/ot_service/hello
hello : 8083;range:OT[root@min ~]# curl http://192.168.19.50:8000/ot_service/hello
hello : 8084;range:OT[root@min ~]# 

6、启用插件

curl -X POST http://localhost:8001/plugins/
–data “name=acl”
–data “config.allow=group1”
–data “config.allow=group2”
–data “config.hide_groups_header=true”

Spring Boot 中使用 JPA 实现领域驱动设计(DDD)涉及对领域模型的精细设计、分层架构的合理划分以及技术实现的精准落地。以下是具体的实践方式和关键步骤: ### 领域模型设计 在 DDD 中,领域模型是核心,它由实体(Entity)、值对象(Value Object)、聚合根(Aggregate Root)等组成。设计时应确保领域模型能够准确反映业务规则和逻辑。例如,在一个订单系统中,订单(Order)可以作为聚合根,包含多个订单项(OrderItem),这些订单项是值对象,没有独立的标识符。 ```java @Entity public class Order implements AggregateRoot<Order> { @Id private String id; private String customerId; private List<OrderItem> items; // 其他字段和方法 } @Embeddable public class OrderItem { private String productId; private int quantity; private BigDecimal price; // 其他字段和方法 } ``` ### 分层架构实现 DDD 推荐四层架构:接口适配器层、应用服务层、领域层和基础设施层。Spring Boot 通过模块化设计支持这种分层结构,确保各层之间的职责分离和解耦。 - **接口适配器层**:负责接收外部请求并将其转换为内部应用服务可以处理的形式。例如,REST 控制器用于接收 HTTP 请求。 - **应用服务层**:协调领域层的业务逻辑执行,通常不包含业务规则本身。 - **领域层**:包含核心业务逻辑和领域模型。 - **基础设施层**:提供持久化、消息队列等技术细节的支持。 ```java @RestController @RequestMapping("/orders") public class OrderController { private final OrderService orderService; public OrderController(OrderService orderService) { this.orderService = orderService; } @PostMapping public ResponseEntity<Order> createOrder(@RequestBody Order order) { Order createdOrder = orderService.createOrder(order); return ResponseEntity.ok(createdOrder); } } ``` ### 使用 JPA 进行持久化 Spring Data JPA 提供了强大的持久化支持,可以通过简单的接口定义来实现对数据库的操作。在 DDD 中,仓储(Repository)模式用于封装对聚合根的持久化逻辑。 ```java public interface OrderRepository extends JpaRepository<Order, String> { } ``` ### 领域事件和发布/订阅机制 领域事件是 DDD 中的重要概念,用于表示领域中发生的重要变化。Spring 提供了 ApplicationEventPublisher 来支持领域事件的发布和监听。 ```java @Component public class OrderEventPublisher { private final ApplicationEventPublisher eventPublisher; public OrderEventPublisher(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } public void publishOrderCreatedEvent(Order order) { eventPublisher.publishEvent(new OrderCreatedEvent(order)); } } @Component public class OrderEventListener { @EventListener public void handleOrderCreatedEvent(OrderCreatedEvent event) { // 处理订单创建后的逻辑 } } ``` ### 避免贫血模型 在使用 JPA 时,很容易陷入“贫血模型”的陷阱,即领域对象仅包含数据,而没有行为。为了实现富领域模型,应在领域对象中封装业务逻辑。 ```java @Entity public class Order { // ...其他字段 public void addItem(Product product, int quantity) { // 添加订单项的业务逻辑 items.add(new OrderItem(product.getId(), quantity, product.getPrice())); } } ``` ### 总结与实践建议 在 Spring Boot 中使用 JPA 实现 DDD 时,应注重领域模型的设计,合理划分各层职责,并充分利用 Spring 框架提供的依赖注入和持久化支持。此外,灵活应用 DDD 的核心概念,如聚合根、值对象、领域事件等,有助于构建出符合业务需求的高质量系统。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值