Micronaut 서비스를 사용하여 마이크로 카프카

오늘, 우리는 것입니다 Apache Kafka서로 항목과 일부 마이크로 서비스를 비동기 통신을 구축 할 수 있습니다. 우리가 사용 Micronaut하는 프레임 워크, Kafka전문 도서관 통합을 제공합니다. 우리가 간단히 예를 들어 시스템의 구조를 설명 할 수 있습니다. 우리는 네 가지가 订单服务마이크로 서비스 : 行程服务,, 司机服务乘客服务. 이러한 응용 프로그램의 구현은 매우 간단합니다. 그들은 메모리에 저장되며, 동일한 연결되어 Kafka인스턴스입니다.

우리의 시스템의 주요 목표는 여행 일정을 고객에게 제공하는 것입니다. 주문 응용 프로그램은 또한 게이트웨이 서비스의 역할을합니다. 그것은 클라이언트의 요청, 역사적 기록의 보존을 수신하고 이벤트를 보낼 orders항목을 참조하십시오. 다른 모든 서비스는 마이크로 모니터에 orders이 주제 및 처리 order-service주문 보냈다. 각 서비스는 이벤트에 포함 된 변경 정보를 전송 자체 전용 마이크로 주제를 가지고 있습니다. 이러한 이벤트는 다른 마이크로 서비스들에 의해 수신된다. 에 도시 된 바와 같이 아키텍처.

IMG

이 글을 읽기 전에,을 숙지 할 필요가있다 Micronaut프레임 워크. 당신은에 의해 설명하는 글 읽기 전에 REST API构建微服务通信的过程: 마이크로 퀵 가이드 서비스를 구축하기 위해 microaut 프레임 워크를 사용하여 .

1. 실행 카프카

로컬 컴퓨터에서 실행하려면 Apache Kafka, 우리는 이미지를 고정 표시기 사용할 수 있습니다. 최신 이미지가 https://hub.docker.com/u/wurstmeister에 의해 공유됩니다. 시작에서 Kafka용기 전에, 우리는 시작해야 kafka사용중인 ZooKeeper서버. 이 경우 Windows실행 Docker기본 주소를 가상 머신입니다 192.168.99.100. 그것은으로 설정해야합니다 Kafka컨테이너의 환경을 제공합니다.

Zookeeper그리고 Kafka선박은 동일한 네트워크에 시작됩니다. 고정 표시기에서 사육사 실행하는 zookeeper서비스를 제공하기 위해 '의 이름을, 그리고 노출 2181포트를. Kafka컨테이너 환경 변수의 사용이 필요합니다 KAFKA_ZOOKEEPER_CONNECT주소를.

$ docker network create kafka
$ docker run -d --name zookeeper --network kafka -p 2181:2181 wurstmeister/zookeeper
$ docker run -d --name kafka -p 9092:9092 --network kafka --env KAFKA_ADVERTISED_HOST_NAME=192.168.99.100 --env KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 wurstmeister/kafka

2. 소개 의존 Micronaut 카프카

사용 Kafka내장 된 microaut응용 프로그램은 HTTP 서버의 존재를 시작할 수 있습니다 또한 HTTP 서버의 부재에서 시작할 수 있습니다. 사용하려면 Micronaut Kafka, 추가 micronaut-kafka종속성에 라이브러리를. 노출 할 경우 HTTP API, 당신은 또한 추가해야합니다 micronaut-http-server-netty:

<dependency>
    <groupId>io.micronaut.configuration</groupId>
    <artifactId>micronaut-kafka</artifactId>
</dependency>
<dependency>
    <groupId>io.micronaut</groupId>
    <artifactId>micronaut-http-server-netty</artifactId>
</dependency>

3. 빌드 주문 microService

订单微服务내장 된 HTTP 서버와 노출 시작하는 단 하나입니다 REST API응용 프로그램. 우리가 할 수있는 이유입니다 Kafka내장 제공하는 Micronaut건강 검진을. 이를 위해, 우리는 먼저 추가해야 micronaut-management의존성 :

<dependency>
    <groupId>io.micronaut</groupId>
    <artifactId>micronaut-management</artifactId>
</dependency>

편의를 위해, 우리는에 통과 할 application.yml자신의 HTTP 인증을 다음과 같은 구성에 정의 된 모든 엔드 포인트의 관리를 활성화 및 비활성화 할 수 있습니다.

endpoints:
  all:
    enabled: true
    sensitive: false

지금, 당신은 HTTP를 해결할 수 : // localhost를이 : 8080 / 건강에서 사용 health check. 우리의 샘플 애플리케이션은 노출 될 添加新订单列出所有以前创建的订单간단한 REST API. 이 엔드 포인트에 노출 아래 Micronaut컨트롤러 :

@Controller("orders")
public class OrderController {

    @Inject
    OrderInMemoryRepository repository;
    @Inject
    OrderClient client;

    @Post
    public Order add(@Body Order order) {
        order = repository.add(order);
        client.send(order);
        return order;
    }

    @Get
    public Set<Order> findAll() {
        return repository.findAll();
    }

}

각 서비스는 마이크로 메모리 저장소 구현을 사용한다. 다음은 订单微服务(Order-Service)저장소 구현 :

@Singleton
public class OrderInMemoryRepository {

    private Set<Order> orders = new HashSet<>();

    public Order add(Order order) {
        order.setId((long) (orders.size() + 1));
        orders.add(order);
        return order;
    }

    public void update(Order order) {
        orders.remove(order);
        orders.add(order);
    }

    public Optional<Order> findByTripIdAndType(Long tripId, OrderType type) {
        return orders.stream().filter(order -> order.getTripId().equals(tripId) && order.getType() == type).findAny();
    }

    public Optional<Order> findNewestByUserIdAndType(Long userId, OrderType type) {
        return orders.stream().filter(order -> order.getUserId().equals(userId) && order.getType() == type)
                .max(Comparator.comparing(Order::getId));
    }

    public Set<Order> findAll() {
        return orders;
    }

}

메모리 스토리지 저장소 Order개체 인스턴스. Order개체는 지정된로 전송 orders의 Kafkatopic. 여기입니다 Order구현 클래스는 :

public class Order {

    private Long id;
    private LocalDateTime createdAt;
    private OrderType type;
    private Long userId;
    private Long tripId;
    private float currentLocationX;
    private float currentLocationY;
    private OrderStatus status;

    // ... GETTERS AND SETTERS
}

4. 비동기 통신 카프카 사용

자, 예를 들어 시스템의 방법에 의해 달성 될 수있다 유스 케이스를 생각하자 - 添加新的行程.

우리가 만든 OrderType.NEW_TRIP새로운 주문 유형입니다. 그 후, (1) 订单服务주문을 생성하고로 보내 orders항목을 참조하십시오. 주문은 세 개의 마이크로 서비스 수신 : 司机服务, 乘客服务行程服务.
(2) 이러한 응용 프로그램의 모든이 새로운 질서를 처리해야합니다. 乘客服务응용 프로그램이 충분한 자금 점검이 있는지 여부를 승객 계정에. 그렇지 않은 경우, 그렇지 않으면 아무것도하지 않고, 여행을 취소했다. 司机服务우리는 (3), 가장 가까운 가능한 드라이버를 찾고 行程服务만들고 새로운 일정을 저장합니다. 司机服务그리고 行程服务자신의 주제 (이벤트를 보낼 것입니다 drivers, trips변경에 관한 정보를 포함한다).

각 이벤트는 다른 될 수 있습니다 microservices예를 들어, (4), 방문 行程服务에서 청취 司机服务여행에 대한 새 드라이버를 할당하기 위해 이벤트

새로운 일정 우리 마이크로 서비스 간의 통신 처리를 추가 할 때 아래 그림 나타낸다.
여기에 그림 삽입 설명이제, 구현 세부 사항을 논의하기 위해 계속하자.

4.1. 보내기 주문

우선, 우리는 카프카 클라이언트는 주제로 메시지를 전송하는 책임이 작성해야합니다. 이름이 우리가 만든 인터페이스는, OrderClient그것에 추가 @KafkaClient및 하나 개 이상의 메소드 선언에 메시지를 보냅니다. 각 방법이 채택되어야한다 @Topic대상 항목 이름 코멘트를 설정. 메소드 매개 변수 위해, 우리는 세 가지 메모를 사용할 수 있습니다 @KafkaKey, @Body또는 @Header. @KafkaKey파티션 들어,이 샘플 애플리케이션의 요구입니다. 다음과 같은 가능한 클라이언트 구현에서, 우리는 사용 @Body주석을.

@KafkaClient
public interface OrderClient {

    @Topic("orders")
    void send(@Body Order order);

}

4.2. 수주

클라이언트가 명령을 전송하면, 그것을 듣고됩니다 orders다른 모든 마이크로 서비스 항목을 수신에. 다음은 司机服务리스너 구현. 리스너 클래스는 OrderListener추가해야 @KafkaListener주석을. 우리는 선언 할 수 있습니다 groupId하나의 응용 프로그램을 방지하기 위해 동일한 메시지의 매개 변수 주석을 여러 인스턴스를 받았다. 그런 다음, 우리는 수신 메시지를 처리하는 방법을 선언합니다. 클라이언트 측 접근 방식과 동일을 채택해야 @Topic우리가 듣고 있기 때문에, 대상 항목 이름 주석을 설정 Order개체를 당신이 사용해야하므로, @Body해당 클라이언트 방법과 동일 - 메모를.

@KafkaListener(groupId = "driver")
public class OrderListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(OrderListener.class);

    private DriverService service;

    public OrderListener(DriverService service) {
        this.service = service;
    }

    @Topic("orders")
    public void receive(@Body Order order) {
        LOGGER.info("Received: {}", order);
        switch (order.getType()) {
            case NEW_TRIP -> service.processNewTripOrder(order);
        }
    }

}

4.3. 다른 주제로 보내기

자, 살펴 보자 방법. 두 개의 서로 다른 사출 콩 : . 신규 주문을 처리 할 때, 승객과 최근에 명령을 보낼 수있는 드라이버를 찾기 위해 노력할 것입니다. 그를 찾은 후, 드라이버의 상태를 변경 하고, 함께 받는 이벤트 객체를 전송 항목을 참조하십시오.司机服务processNewTripOrderDriverServiceKafka Client
OrderClientDriverClientUNAVAILABLEDriverdrivers

@Singleton
public class DriverService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DriverService.class);

    private DriverClient client;
    private OrderClient orderClient;
    private DriverInMemoryRepository repository;

    public DriverService(DriverClient client, OrderClient orderClient, DriverInMemoryRepository repository) {
        this.client = client;
        this.orderClient = orderClient;
        this.repository = repository;
    }

    public void processNewTripOrder(Order order) {
        LOGGER.info("Processing: {}", order);
        Optional<Driver> driver = repository.findNearestDriver(order.getCurrentLocationX(), order.getCurrentLocationY());
        driver.ifPresent(driverLocal -> {
            driverLocal.setStatus(DriverStatus.UNAVAILABLE);
            repository.updateDriver(driverLocal);
            client.send(driverLocal, String.valueOf(order.getId()));
            LOGGER.info("Message sent: {}", driverLocal);
        });
    }

    // ...
}

이다 에 대한 구현 메시지 보내기 항목을 참조하십시오. 우리가해야하기 때문에 가 관련되어, 그래서 우리는 사용 주석 매개 변수를. 포함 할 필요가 없습니다 우측 스트로크 엔드 수신기에 할당 된 클래스를.Kafka Client司机服务driverDriverOrder@HeaderorderIdDriver

@KafkaClient
public interface DriverClient {

    @Topic("drivers")
    void send(@Body Driver driver, @Header("Order-Id") String orderId);

}

서비스 간의 4.4. 통신

에 의해 DriverListener영수증 @KafkaListener行程服务성명. 그것은으로 들어오는를 수신 trip항목을 참조하십시오. 다음과 같이 유사 파라미터 클라이언트 전송 방법 및 수신 방법 :

@KafkaListener(groupId = "trip")
public class DriverListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(OrderListener.class);

    private TripService service;

    public DriverListener(TripService service) {
        this.service = service;
    }

    @Topic("drivers")
    public void receive(@Body Driver driver, @Header("Order-Id") String orderId) {
        LOGGER.info("Received: driver->{}, header->{}", driver, orderId);
        service.processNewDriver(driver);
    }

}

마지막 단계는 orderId, 쿼리 스트로크 협회되도록 전체 처리를 종료한다.TripdriverId

@Singleton
public class TripService {

    private static final Logger LOGGER = LoggerFactory.getLogger(TripService.class);

    private TripInMemoryRepository repository;
    private TripClient client;

    public TripService(TripInMemoryRepository repository, TripClient client) {
        this.repository = repository;
        this.client = client;
    }


    public void processNewDriver(Driver driver, String orderId) {
        LOGGER.info("Processing: {}", driver);
        Optional<Trip> trip = repository.findByOrderId(Long.valueOf(orderId));
        trip.ifPresent(tripLocal -> {
            tripLocal.setDriverId(driver.getId());
            repository.update(tripLocal);
        });
    }

    // ... OTHER METHODS

}

5. 추적

우리가 사용할 수있는 Micronaut Kafka분산 추적을 사용 쉽게. 우선, 우리는 활성화하고 구성해야 Micronaut추적을. 이렇게하려면, 먼저 우리는 몇 가지 종속성을 추가해야합니다 :

<dependency>
    <groupId>io.micronaut</groupId>
    <artifactId>micronaut-tracing</artifactId>
</dependency>
<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave-instrumentation-http</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-reporter</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.opentracing.brave</groupId>
    <artifactId>brave-opentracing</artifactId>
</dependency>
<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-kafka-client</artifactId>
    <version>0.0.16</version>
    <scope>runtime</scope>
</dependency>

우리는 또한 필요한 application.yml구성 파일의 지프 킨의 트랙 주소의 구성을.

tracing:
  zipkin:
    enabled: true
    http:
      url: http://192.168.99.100:9411
    sampler:
      probability: 1

응용 프로그램을 시작하기 전에, 우리는 실행해야 Zipkin컨테이너를 :

$ docker run -d --name zipkin -p 9411:9411 openzipkin/zipkin

6. 요약

이 기사에서는 배우게됩니다 Apache Kafka마이크로 아키텍처 프로세스를 구축하는 비동기 통신 서비스를 사용. 나는 제시해야 Microaut Kafka쉽게 선언 할 수 있습니다 도서관의 가장 중요한 특징, Kafka서비스가 마이크로 활성화를 위해, 생산자와 소비자의 주제 健康检查分布式跟踪. 나는 고객의 요구에 따라 새로운 경로를 추가하는 등, 우리의 시스템에 대한 간단한 시나리오를 설명했다. 본 예시적인 시스템의 전체 구현은 GitHub에의 참조하세요 원본

원본 링크 : HTTPS : //piotrminkowski.wordpress.com/2019/08/06/kafka-in-microservices-with-micronaut/

저자 : 표트르의

번역 : 동아

추천

출처www.cnblogs.com/springforall/p/11610643.html