grpc 实现

This commit is contained in:
三丙
2024-10-23 17:07:57 +08:00
parent 7445d4e3f0
commit 5a1b4f8303
21 changed files with 715 additions and 141 deletions

View File

@@ -0,0 +1,159 @@
/**
* 抖音关注:程序员三丙
* 知识星球https://t.zsxq.com/j9b21
*/
package sanbing.jcpp.protocol.adapter;
import io.grpc.CompressorRegistry;
import io.grpc.DecompressorRegistry;
import io.grpc.Server;
import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder;
import io.grpc.netty.shaded.io.netty.channel.ChannelOption;
import io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoopGroup;
import io.grpc.netty.shaded.io.netty.channel.socket.nio.NioServerSocketChannel;
import io.grpc.stub.StreamObserver;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import sanbing.jcpp.infrastructure.util.mdc.MDCUtils;
import sanbing.jcpp.infrastructure.util.trace.TracerContextUtil;
import sanbing.jcpp.infrastructure.util.trace.TracerRunnable;
import sanbing.jcpp.proto.gen.ProtocolDownlinkInterfaceGrpc.ProtocolDownlinkInterfaceImplBase;
import sanbing.jcpp.proto.gen.ProtocolProto.DownlinkRequestMessage;
import sanbing.jcpp.proto.gen.ProtocolProto.DownlinkResponseMessage;
import sanbing.jcpp.proto.gen.ProtocolProto.TracerProto;
import sanbing.jcpp.protocol.domain.ProtocolSession;
import sanbing.jcpp.protocol.provider.ProtocolSessionRegistryProvider;
import javax.annotation.PreDestroy;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import static sanbing.jcpp.infrastructure.util.config.ThreadPoolConfiguration.JCPP_COMMON_THREAD_POOL;
/**
* @author baigod
*/
@Service
@Slf4j
@ConditionalOnExpression("'${service.type:null}'=='monolith' || '${service.type:null}'=='protocol'")
public class DownlinkGrpcService extends ProtocolDownlinkInterfaceImplBase {
@Value("${service.protocol.rpc.port}")
private int rpcPort;
@Value("${service.protocol.rpc.boss}")
private int rpcBoss;
@Value("${service.protocol.rpc.worker}")
private int rpcWorker;
@Value("${service.protocol.rpc.so-rcvbuf}")
private int rpcNettySoRcvbuf;
@Value("${service.protocol.rpc.so-sndbuf}")
private int rpcNettySoSndbuf;
@Value("${service.protocol.rpc.no-delay}")
private boolean rpcNettyNoDelay;
@Value("${service.protocol.rpc.max-inbound-message-size}")
private int maxInboundMessageSize;
@Value("${service.protocol.rpc.max-concurrent-calls-per-connection}")
private int maxConcurrentCallsPerConnection;
@Value("${service.protocol.rpc.client-max-keep-alive-time-sec}")
private int clientMaxKeepAliveTimeSec;
@Resource
ProtocolSessionRegistryProvider protocolSessionRegistryProvider;
private Server server;
@PostConstruct
public void init() throws Exception {
log.info("Initializing Protocol Downlink Grpc service!");
NettyServerBuilder builder = NettyServerBuilder.forPort(this.rpcPort)
.bossEventLoopGroup(new NioEventLoopGroup(this.rpcBoss))
.workerEventLoopGroup(new NioEventLoopGroup(this.rpcWorker))
.withOption(ChannelOption.SO_RCVBUF, rpcNettySoRcvbuf)
.withChildOption(ChannelOption.SO_SNDBUF, rpcNettySoSndbuf)
.withChildOption(ChannelOption.TCP_NODELAY, rpcNettyNoDelay)
.compressorRegistry(CompressorRegistry.getDefaultInstance())
.decompressorRegistry(DecompressorRegistry.getDefaultInstance())
.channelType(NioServerSocketChannel.class)
.permitKeepAliveTime(this.clientMaxKeepAliveTimeSec, TimeUnit.SECONDS)
.maxInboundMessageSize(maxInboundMessageSize)
.maxConcurrentCallsPerConnection(maxConcurrentCallsPerConnection)
.directExecutor()
.keepAliveTime(5, TimeUnit.MINUTES)
.keepAliveTimeout(10, TimeUnit.SECONDS)
.permitKeepAliveWithoutCalls(true)
.addService(this);
this.server = builder.build();
log.info("Going to start RPC server using port: {}", this.rpcPort);
try {
this.server.start();
} catch (Exception e) {
log.error("Failed to start RPC server!", e);
throw e;
}
log.info("Protocol Downlink Grpc service initialized!");
}
@PreDestroy
public void destroy() {
if (this.server != null) {
this.server.shutdownNow();
}
}
@Override
public StreamObserver<DownlinkRequestMessage> onDownlink(StreamObserver<DownlinkResponseMessage> responseObserver) {
return new StreamObserver<>() {
@Override
public void onNext(DownlinkRequestMessage downlinkMsg) {
TracerProto tracerProto = downlinkMsg.getTracer();
TracerContextUtil.newTracer(tracerProto.getId(), tracerProto.getOrigin(), tracerProto.getTs());
MDCUtils.recordTracer();
log.debug("收到Grpc下行请求 {}", downlinkMsg);
JCPP_COMMON_THREAD_POOL.execute(new TracerRunnable(() -> {
UUID protocolSessionId = new UUID(downlinkMsg.getSessionIdMSB(), downlinkMsg.getSessionIdLSB());
ProtocolSession protocolSession = protocolSessionRegistryProvider.get(protocolSessionId);
try {
if (protocolSession != null) {
protocolSession.onDownlink(downlinkMsg);
} else {
log.info("下发报文时Session未找到 sessionId: {}", protocolSessionId);
}
} catch (Exception e) {
log.warn("下发报文时处理失败 sessionId: {}", protocolSessionId, e);
}
}));
}
@Override
public void onError(Throwable t) {
log.error("Failed to deliver message from client!", t);
}
@Override
public void onCompleted() {
try {
responseObserver.onCompleted();
} catch (Exception e) {
log.error("onCompleted error ", e);
}
}
};
}
}

View File

@@ -34,10 +34,10 @@ public class DefaultProtocolSessionRegistryProvider implements ProtocolSessionRe
private static final int INIT_CACHE_LIMIT = 100_000;
private static final int MAXIMUM_SIZE = 1_000_000;
@Value("${service.protocols.sessions.default-inactivity-timeout-in-sec}")
@Value("${service.protocol.sessions.default-inactivity-timeout-in-sec}")
private int defaultInactivityTimeoutInSec;
@Value("${service.protocols.sessions.default-state-check-interval-in-sec}")
@Value("${service.protocol.sessions.default-state-check-interval-in-sec}")
private int defaultStateCheckIntervalInSec;
@Getter