通常,当我考虑一个新的库或新技术时,我会创建一个小型的POC或测试程序来了解它。所以我对gRPC-弹簧-启动器做了。下面贴出了一个简单的示例代码。
这个示例已经在复杂性上进行了扩展,最终,库找到了进入生产代码的途径。到目前为止,它已经在中等负荷下存活了很多次。请注意,生产服务本身自然不是客户端。但是生产gRPC服务实际上是其他gRPC服务的客户端。
现在,我正在考虑编写某种单元与集成之间的测试,在测试中,我从其他gRPC服务(例如,从静态本地资源中提取数据)的本地实例(从单个实例开始)。基本上,这个测试代码看起来非常类似于下面发布的测试代码。
然而,一旦我们在forEachRemaining()中投票结果,测试就会挂起:我怀疑ClientCalls#waitAndDrain (io.grpc:grpc-stub)中存在死锁。
有趣的是,如果客户端是“手动”创建的,即没有使用第三方Spring扩展,就不会发生这种情况:
ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:9091")
.defaultLoadBalancingPolicy("round_robin")
.usePlaintext()
.build();
StockStaticDataRequestServiceBlockingStub stub = StockStaticDataRequestServiceGrpc.newBlockingStub(channel);我使用SpringBoot2.6.3、2.13.1、gRPC 1.44.0、proto3.19.2和netty4.1.73来实现它的价值。
现在,我想知道这里是否有人遇到了类似的问题,或者在我试图更多地了解gRPC的内部工作时,是否可以给我一些提示。
增加了GH样本项目。main分支包含了我在开始时选择的--也许是可疑的--测试设置,分支是一些改进,比如使用@Abhijit的grpc-test库。到目前为止,测试都是绿色。
grpc:
client:
stocks:
address: 'static://localhost:9091'
enableKeepAlive: false
negotiationType: plaintext
server:
port: 9092@SpringBootTest
class TestGrpc {
@GrpcClient("stocks")
private StockStaticDataRequestServiceBlockingStub stub;
@BeforeAll
public static void setUp() throws Exception {
final Server server = ServerBuilder
.forPort(9091)
.addService(new StockStaticDataRequestTestService())
.build();
server.start();
final Thread serverThread = new Thread(() -> {
try {
server.awaitTermination();
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
}
});
serverThread.setDaemon(false);
serverThread.start();
}
@Test
void testClient() {
StockStaticManyDataRequest request = StockStaticManyDataRequest.newBuilder()
.addAllTickerSymbols(List.of("AAPL"))
.build();
stub.getManyStockStatics(request).forEachRemaining(security -> {
LOG.info("security={}", security);
});
}
}public class StockStaticDataRequestTestService extends StockStaticDataRequestServiceImplBase {
@Override
public void getManyStockStatics(StockStaticManyDataRequest request, StreamObserver<Security> responseObserver) {
responseObserver.onNext(Security.newBuilder()
.setSecurity("TEST-MANY")
.build());
responseObserver.onNext(Security.newBuilder()
.setSecurity("TEST-MORE")
.build());
responseObserver.onCompleted();
}
}message Security {
string tickerSymbol = 1;
string security = 2;
}
message StockStaticManyDataRequest {
repeated string tickerSymbols = 1;
}
service StockStaticDataRequestService {
rpc getManyStockStatics(StockStaticManyDataRequest) returns (stream Security) {}
}发布于 2022-02-19 20:14:08
我认为问题可能在于您根本不应该启动服务器。应该将一些grpc启动启动注释添加到将启动/停止服务器的测试配置类中。请看这里的细节。
https://yidongnan.github.io/grpc-spring-boot-starter/en/server/testing.html#integration-tests
我也尝试让你有工作,但服务器一旦启动,真的不会关闭。这使得下一个运行的测试套件在尝试启动时由于端口冲突而失败。
这是我的考试课。
@Slf4j
@SpringBootTest
@ActiveProfiles("test")
@SpringJUnitConfig(classes = { ServiceIntegrationTestConfiguration.class })
@DirtiesContext
class TestGprc {
@GrpcClient("stocks")
private StockStaticDataRequestServiceBlockingStub stub;
/**
* @throws java.lang.Exception
*/
@BeforeAll
static void setUpBeforeClass() throws Exception {
log.info("setUpBeforeClass");
}
/**
* @throws java.lang.Exception
*/
@AfterAll
static void tearDownAfterClass() throws Exception {
log.info("tearDownAfterClass");
}
/**
* @throws java.lang.Exception
*/
@BeforeEach
void setUp() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@AfterEach
void tearDown() throws Exception {
}
@Test
@DirtiesContext
void testClient() {
StockStaticManyDataRequest request = StockStaticManyDataRequest.newBuilder()
.addAllTickerSymbols(List.of("AAPL"))
.build();
stub.getManyStockStatics(request).forEachRemaining(security -> {
log.info("security={}", security);
});
}
}这是配置项目。
@Configuration
@ImportAutoConfiguration({ GrpcServerAutoConfiguration.class, // Create required server beans
GrpcServerFactoryAutoConfiguration.class, // Select server implementation
GrpcClientAutoConfiguration.class,
GrpcStarterApplication.class})
public class ServiceIntegrationTestConfiguration {
// add mock beans here of needed.
}我对这些房产的超车。见应用程序-test.yaml
grpc:
client:
stocks:
address: in-process:test
enableKeepAlive:
negotiationType:
server:
inProcessName: test
port: -1我在这里发布了整个maven项目:https://github.com/aerobiotic/grpc-spring-starter
只需复制它和mvn干净安装:-)
就您的死锁而言,您的生产代码是:
https://stackoverflow.com/questions/71184542
复制相似问题