다른 모듈에 대한 유틸리티 범위. 인스턴스의 필드 값을 설정 및 가져오거나 LambdaMetafactory
에서 생성된 기능 인터페이스를 통해 생성자에 액세스할 수 있는 LambdaReflection
이 포함되어 있습니다.
모든 버퍼 구현을 지원하는 추상 직렬화 라이브러리입니다. 기본 유형의 필드, Proto4jSerializable
구현 또는 기타 @AutoSerializable
멤버로 구성된 @AutoSerializable
로 표시된 클래스를 자동으로 (역)직렬화합니다.
상속도 지원합니다. 직렬화 가능 클래스는 다른 @AutoSerializable
확장할 수 있으며, 이 경우 모든 상위 필드도 전이적으로 직렬화됩니다.
직렬화 중에 무시해야 하는 필드에는 @Transient
주석을 달아야 합니다.
구성 가능한 안정성을 갖춘 맞춤형 UDP 기반 구현을 갖춘 네트워킹 라이브러리입니다.
Proto4jServer
및 Proto4jClient
사용하면 소켓 간에 데이터그램을 사용하여 데이터를 전송할 수 있습니다.
기본적으로 전송된 모든 데이터는 순서가 지정되고 신뢰할 수 있으며 여러 UDP 패킷으로 분할되어 수신자 측에서 다시 결합되어 전달이 보장됩니다.
전송되는 모든 UDP 패킷의 구조는 다음과 같습니다.
데이터 전송 방법을 선택하는 것은 귀하의 선택입니다. 전송 방법에 대한 플래그를 지정하여 구성할 수 있습니다. 그것들은 모두 Proto4jPacket
에 있습니다. Flag
.
다음 플래그를 사용할 수 있습니다.
이름 | 값 | 의미 |
---|---|---|
CONFIRMATION | 0x01 | 이 패킷이 다른 패킷이 성공적으로 수신되었음을 나타내는 표시임을 표시합니다. 전송 신뢰성을 위해 필요합니다. 일반적으로 내부용으로만 사용됩니다. |
PARTIAL | 0x02 | 이 UDP 패킷이 더 큰 패킷의 일부임을 표시합니다. CONFIRMATION 플래그와 함께 사용되면 더 큰 패킷의 일부가 전달되었음을 나타냅니다. |
UNORDERED | 0x04 | 이 패킷이 순서 없이 처리될 수 있음을 표시합니다. |
UNSIGNED_BODY | 0x08 | 기본적으로 전송된 모든 패킷은 CRC32를 사용하여 서명되지만 해당 플래그가 지정된 패킷의 경우 패킷 헤더만 서명됩니다. 이는 패킷에 유효하지 않은 바이트가 포함될 수 있음을 의미합니다(데이터 손실은 보장되지 않지만). |
UNRELIABLE | 0x10 | 이 패킷을 확인이 필요하지 않은 것으로 표시합니다. 수신자가 이 패킷을 수신하지 못하는 경우 발신자는 이에 대해 아무 조치도 취하지 않습니다. |
INDIVISIBLE | 0x20 | UDP 패킷은 길이가 제한되어 있으므로 Proto4J는 대용량 데이터를 여러 개의 작은 패킷으로 분할합니다. 이 플래그는 패킷이 단일 패킷의 크기 제한을 초과하는 경우 분할을 수행하는 대신 예외가 발생함을 나타냅니다. |
이 수준에서는 핸드쉐이킹이나 핑이 지원되지 않지만 Proto4jSocket
.setInitialPacketHandler(BiConsumer<C, Proto4jPacket>)
메서드를 사용하여 고유한 패킷 핸들러를 설정할 수 있습니다. 이 지점으로 오는 패킷은 CONFIRMATION
또는 PARTIAL
플래그로 표시되지 않으므로 그곳에서 처리되는 모든 Proto4jPacket
인스턴스에는 발신자가 보낸 정확한 데이터(최대 UNSIGNED_BODY
플래그까지)가 포함됩니다.
또한 소켓을 시작하면 소켓 간 통신 논리를 시작하는 데 도움이 될 수 있는 CompletionStage<Void>
반환됩니다.
Proto4J 에서 소켓을 인스턴스화하려고 할 때 작업자 및 핸들러 스레드 양을 소켓 생성자에 전달해야 합니다.
작업자는 소켓에서 데이터를 읽는 데에만 사용됩니다.
핸들러는 새 패킷이 나타날 때 논리를 처리하는 데 사용됩니다.
이는 이전 수준보다 높은 수준의 인터페이스입니다. 작업을 시작하려면 Proto4jHighServer
및 Proto4jHighClient
또는 기본 구현인 BaseProto4jHighServer
및 BaseProto4jHighClient
를 살펴보세요.
클라이언트가 처음에 서버와 상호 작용할 때 핸드셰이킹이 시작됩니다. 완료 후 서버와 클라이언트는 연결이 끊어지지 않도록 서로 ping합니다.
Low level 과 달리 원시 바이트를 조작하는 것뿐만 아니라 복잡한 엔터티를 사용하여 네트워크를 통해 높은 수준의 패킷을 보낼 수 있습니다. 이렇게 하려면 EnumeratedProto4jPacket
또는 CallbackProto4jPacket
을 확장하는 고유한 클래스를 생성하세요. 이를 작동시키기 위해 해야 할 일은 write(Buffer)
및 read(Buffer)
메소드를 구현하고 양쪽의 PacketManager
에 패킷을 등록하는 것뿐입니다.
또한 Proto4jPacket
대신 해당 패킷과 작동하는 대체 PacketHandler
클래스가 있습니다.
전송된 패킷에 응답하는 일부 패킷을 기다리는 것이 일반적인 시나리오입니다. 이러한 기능은 이미 이 수준에서 구현되었습니다. 최대 대기 시간을 지정하고 원하는 방식으로 응답을 처리할 수 있습니다. 이는 HighChannel
사용하여 초기 패킷을 전송함으로써 수행될 수 있습니다. sendWithCallback(CallbackProto4jPacket)
메서드.
다음은 모듈이 내부적으로 작동하는 방식에 영향을 미치는 데 사용할 수 있는 시스템 속성 목록입니다. 모든 시간 값은 밀리초 단위로 지정됩니다.
이름 | 기본값 | 설명 |
---|---|---|
proto4j.maxDatagramSize | 508 | 허용되는 최대 데이터그램 크기입니다. 전체 UDP 패킷 크기를 계산한다는 점에 유의하세요. |
proto4j.maxSequenceNumber | 2_000_000_000 | 패킷의 최대 시퀀스 번호입니다. 내부 카운터가 이 값에 도달하면 0으로 재설정됩니다. |
proto4j.reliabilityThreshold | 20 | 확인되지 않은( UNRELIABLE 플래그로 표시되지 않은) 패킷의 지연입니다. |
proto4j.callbacksRegistryDelay | 100 | 콜백의 레지스트리 검사가 시간 초과된 콜백을 검색하는 속도입니다. |
proto4j.callbacksInitialDelay | 500 | 패킷이 전송될 때마다 사용되는 기본 시간이며 대기 시간이 명시적으로 지정되지 않을 때마다 대기됩니다. |
proto4j.highTimeout | 10_000 | 서버가 오랫동안 클라이언트로부터 패킷을 수신하지 않으면 후자의 연결이 끊어집니다. |
proto4j.highPingDelay | 1_000 | 서버가 해당 기간 동안 클라이언트와의 수신 또는 전송이 없었다고 표시하면 클라이언트에 응답을 보내고 핑 패킷을 기다립니다. |
이는 높은 수준의 API보다 높은 수준 의 API입니다. 수동으로 패킷을 구현하고 처리하는 대신 서비스를 통해 작업합니다.
작업을 시작하려면 RpcServer
및 RpcClient
사용하십시오.
이 수준의 서버는 라우팅 목적으로만 사용되지만 클라이언트는 서비스 사용자와 구현자 역할을 모두 수행합니다.
서비스는 인터페이스 부분과 구현 부분으로 구성됩니다. 서비스 사용자로서 RpcClient
.getServiceManager().getService(Class<S>)
통해 서비스 인터페이스 인스턴스를 얻을 수 있습니다. 모든 메소드는 등록된 구현으로 프록시되며 원격으로 실행됩니다.
자신만의 서비스를 만들려면 인터페이스로 시작하고 @Proto4jService로 주석을 답니다.
서비스 인터페이스는 기본 및 정적 메소드를 가질 수 있지만 해당 반환 유형은 void
, 직렬화 가능 또는 이전 유형의 CompletionStage
여야 합니다. 또한 모든 인수는 직렬화 가능해야 합니다.
직렬화 가능한 유형은 다음과 같습니다.
String
과 UUID
@AutoSerializable
로 주석이 달린 클래스BufferSerializable
구현하는 클래스List
, Set
및 Map
등록된 모든 서비스 구현에서 메소드를 실행해야 하는 경우 @Broadcast
주석을 달아야 하지만 이러한 메소드는 void
또는 CompletionStage<Void>
만 반환할 수 있습니다.
기본적으로 메서드를 호출하면 무작위로 구현되어 실행됩니다. 실행 분포를 제어하려면 @Index
로 메서드 인수 중 일부를 표시하세요. 메서드가 호출될 때마다 표시된 인수의 해시 코드를 기반으로 구현이 선택됩니다.
서비스가 등록될 때마다 모든 메소드는 정수 식별자로 변환됩니다. 동일한 식별자를 가진 두 가지 방법이 있을 수는 없지만 그러한 상황이 발생할 수 있습니다. 이를 처리하려면 명시적으로 지정된 정적 식별자가 있는 @MethodIdentifier
로 메서드에 주석을 답니다.
이미 서비스 인터페이스를 만들었으면 이제 구현을 만들고 RpcClient
.getServiceManager().registerService(Class<S>, I)
사용하여 등록하세요.
일반적인 시나리오는 두 클라이언트 세트에 서비스 인터페이스가 있지만 그 중 하나만 구현되는 경우입니다.
이는 기본 RPC보다 높은 수준의 계층입니다.
분산 백엔드(즉, 마이크로서비스)를 생성할 때 실패 지점 수를 최소화하는 것이 좋습니다. 이전 섹션에서 설명한 구성표에는 단일 서버 인스턴스인 단 하나의 실패 지점이 있습니다. Conclave는 동시에 작동하는 서버 세트입니다.
Conclave 의 모든 서버는 서로 연결되어 있지만 모든 클라이언트는 단일 서버에만 연결됩니다. RPC 쿼리는 전체 네트워크에 걸쳐 원활하게 배포 및 라우팅되므로 걱정할 필요가 없습니다.
Conclave 작업을 시작하려면 RpcConclaveServer
및 RpcConclaveClient
를 살펴보세요. 이들 중 하나를 인스턴스화하려면 모든 서버의 대상 지점 목록인 List<InetSocketAddress>
를 전달해야 합니다.
전송 모듈의 경우 RPC 모듈에서 찾고 있는 시스템 속성 집합이 있습니다.
이름 | 기본값 | 설명 |
---|---|---|
proto4j.conclaveWorkers | 2 | 각 서버 내부 클라이언트(다른 서버에 액세스하는 데 사용됨)에서 사용하는 작업자 스레드 수입니다. |
proto4j.conclaveHandlers | 2 | 각 서버 내부 클라이언트(다른 서버에 액세스하는 데 사용됨)에서 사용하는 핸들러 스레드 수입니다. |
proto4j.conclaveTimeout | 1_000 | 다른 서버와의 핸드셰이크가 완료될 때까지 서버가 기다리는 최대 시간입니다. 그렇지 않으면 후자를 실행되지 않는 것으로 간주하여 연결 시도를 종료합니다. 이 경우 연결은 시작 시 다른 연결의 요청이 있는 경우에만 다시 시작됩니다. |