Я имею:
Протофиль находится отдельно от сервера и клиента < /p>
Код: Выделить всё
syntax = "proto3";
package my.proto.file.proto.event;
import "google/protobuf/timestamp.proto";
import "google/protobuf/empty.proto";
message EventsRequest {
string serviceName = 1;
}
message EventSaveRequest {
Event event = 1;
string eventType = 2;
}
message Event {
string eventId = 1;
string source = 2;
string login = 3;
string role = 4;
string operation = 5;
string description = 6;
optional google.protobuf.Timestamp createdAt = 7;
}
message EventResponse {
repeated Event events = 1;
}
message SaveEventResponse {
Event events = 1;
}
service EventService {
rpc getEventsByServiceName(EventsRequest) returns (stream EventResponse);
rpc saveEvents(EventSaveRequest) returns (SaveEventResponse);
}
Код: Выделить всё
...
grpc:
client:
my-service-client:
address: "localhost:9090"
negotiationType: PLAINTEXT
...
Код: Выделить всё
...
dependencyManagement {
dependencies {
...
dependency("my.proto.file:eventmanager-grpc-proto:1.0.0-SNAPSHOT")
dependency("net.devh:grpc-client-spring-boot-starter:3.1.0.RELEASE")
}
}
dependencies {
implementation("net.devh:grpc-client-spring-boot-starter")
implementation("my.proto.file:eventmanager-grpc-proto")
...
}
...
Код: Выделить всё
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import my.proto.file.proto.event.EventServiceGrpc;
import my.proto.file.proto.event.EventOuterClass;
@Slf4j
@Service
public class EventService {
@GrpcClient("my-service-client")
private EventServiceGrpc.EventServiceBlockingStub blockingStub;
public EventOuterClass.EventResponse getEventsByServiceName(String serviceName) {
EventOuterClass.EventsRequest request = EventOuterClass.EventsRequest
.newBuilder()
.setServiceName(serviceName)
.build();
EventOuterClass.EventResponse response = blockingStub.getEventsByServiceName(request).next();
return response;
}
... // here is the call to saveEvents
}
Код: Выделить всё
...
grpc:
server:
port: 9090
reflection-service-enabled: true
shutdown-grace-period: 0
...
Код: Выделить всё
...
dependencies {
...
implementation("io.grpc:grpc-api:1.63.0")
implementation("io.grpc:grpc-stub:1.63.0")
implementation("io.grpc:grpc-protobuf:1.63.0")
implementation("net.devh:grpc-server-spring-boot-starter:3.1.0.RELEASE")
testImplementation("net.devh:grpc-client-spring-boot-starter:3.1.0.RELEASE")
implementation("org.springdoc:springdoc-openapi-starter-webflux-api")
implementation("org.springdoc:springdoc-openapi-starter-webflux-ui")
implementation("io.netty:netty-all:4.1.110.Final")
implementation("org.javers:javers-core")
implementation("de.codecentric:spring-boot-admin-starter-client:3.3.2")
implementation("io.projectreactor:reactor-tools")
implementation("io.r2dbc:r2dbc-postgresql:0.8.13.RELEASE")
//compile only
compileOnly("org.projectlombok:lombok")
compileOnly ("io.grpc:grpc-netty:1.63.0")
compileOnly ("io.grpc:grpc-protobuf:1.63.0")
compileOnly ("io.grpc:grpc-stub:1.63.0")
compileOnly ("io.grpc:grpc-services:1.63.0")
testImplementation("io.projectreactor:reactor-test")
testImplementation("io.grpc:grpc-testing:1.63.0")
testImplementation("com.salesforce.servicelibs:reactor-grpc-stub:1.2.4")
...
}
dependencyManagement {
...
dependencies {
...
dependency("org.projectlombok:lombok-mapstruct-binding:0.2.0")
dependency("org.springdoc:springdoc-openapi-starter-webflux-api:2.5.0")
dependency("org.springdoc:springdoc-openapi-starter-webflux-ui:2.5.0")
dependency("my.proto.file:eventmanager-grpc-proto:1.0.0-SNAPSHOT")
dependency("org.springframework.cloud:spring-cloud-starter-sleuth:3.1.11")
dependency("org.springframework.cloud:spring-cloud-sleuth-zipkin:3.1.11")
dependency("io.projectreactor:reactor-core:3.6.2")
...
}
}
...
import my.proto.file.eventmanager.interceptors.LogGrpcInterceptor;
import my.proto.file.eventmanager.mapper.EventMapper;
import my.proto.file.eventmanager.model.Event;
import my.proto.file.proto.event.EventOuterClass;
import my.proto.file.proto.event.ReactorEventServiceGrpc;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.annotation.NewSpan;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Duration;
@GrpcService(interceptors = {LogGrpcInterceptor.class})
@Slf4j
@RequiredArgsConstructor
public class GrpcImplEventService extends ReactorEventServiceGrpc.EventServiceImplBase {
private static final Long TIMEOUT_MILLIS = 5000L;
private final EventService eventService;
private final Tracer tracer;
private final Validator validator;
@Override
@NewSpan
public Flux getEventsByServiceName(EventOuterClass.EventsRequest request) {
Flux w = eventService.getEventsByServiceName(request.getServiceName());
return Mono.just(request)
.flatMapMany(req -> eventService.getEventsByServiceName(req.getServiceName())
.doOnNext(ev -> spanTag("source", req.getServiceName()))
.map(
ev -> EventOuterClass.EventResponse.newBuilder().addEvents(EventMapper.INSTANCE.map(ev)).build()
)
)
.timeout(Duration.ofMillis(TIMEOUT_MILLIS))
.doOnError(this::spanError)
.doOnNext(response -> log.info("Events count received: {}", response.getEventsCount()));
}
... // here is the implementation saveEvents, validate, spanTag, spanError
}
< /code>
Когда я звоню в службу клиента, клиент возвращает ошибки < /p>
[grpc-nio-worker-elg-1 -5] отладка N.D.B.G.C.N.Discoveryclientnameresolver-Запланированное разрешение для Localhost: 9090 < /p>
< /blockquote>
[grpc-default-executor-0] Ошибка n.d.b.g.c.n. DiscoveryClientNamerESolver-Нет серверов для LocalHost: 9090 < /p>
< /blockquote>
[grpc-default-executor-0] Warn io.grpc.internalal . ManagedChannelImpl - [Канал : (Localhost: 9090)] не удалось разрешить имя. Status = status {code = novailable, description = не найдено серверов для Localhost: 9090, canect = null} < /p>
< /blockquote>
[grpc -default-Executor-0] отладка io.grpc.channellogger-[канал : (localhost: 9090)] вход в состояние transient_failure с Picker: FixedResultPicker (pickResult {subChannel = nul Недоступно, описание = нет серверов, не найденных для Localhost: 9090, canev = null}, drop = false}) < /p>
< /blockquote>
[grpc -default-Executor-0] Debug I.G.I.BackOffPolicyRetryScheduler-Бэкф в расписание разрешения DNS для 6 987 791 831ns < /p>
< /blockquote>
[http-nio -8081-EXEC-2] Ошибка O.A.C.C.C.C. [. Серверы не найдены для Localhost: 9090] с основной причиной io.grpc.statusruntimeexception: недоступно: нет серверов для Localhost: 9090 < /p>
< /blockquote>
< /p>
< /blockquote>
[GRPC-DEFAULT-EXECUTOR-0] Ошибка n.d.b.g.c.n.discoveryclientnameresolver-Нет серверов, найденных для Localhost: 9090 < /p>
< /blockquote>
[grpc -default-Executor-0] Warn io.grpc.internal.managedChannelimpl-[Канал : (Localhost: 9090)] не удалось разрешить имя. Status = status {code = novailable, description = не найдено серверов для Localhost: 9090, canect = null} < /p>
< /blockquote>
[grpc -default-Executor-0] Debug io.grpc.channellogger-[канал : (localhost: 9090)] не удалось разрешить имя: code = noadailable, описание = нет серверов для Localhost: 9090, причина = NULL } < /p>
< /blockquote>
[grpc-default-executor-0] отладка io.grpc.channellogger-[канал : ( localhost: 9090)] вход в состояние transient_failure с Picker: FixedResultPicker (pickResult {subChannel = null, StreamTracerFactory = null, Status = status {code = недоступен, description = нет серверов для LocalHost: 9090, причина = null}, dop = false}}. ) < /p>
< /blockquote>
[http-nio-8081-exec-2] отладка io.grpc.context-replid существовать. Использование java.lang.lang.classnotfoundexception: io.grpc.override.contextStorageOverride < /p>
< /blockquote>
p.s.
Если я создаю свой собственный боб и заменяю его вместо Grpcclient, все будет работать. Ниже приведен пример работы клиента.
my bean
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.stub.AbstractBlockingStub;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import my.proto.file.proto.event.EventServiceGrpc;
import my.proto.file.proto.event.EventServiceGrpc.EventServiceBlockingStub;
@Configuration
@ComponentScan(basePackages = "accessportal.controller")
public class MyBeans {
@Bean
public EventServiceBlockingStub EventServiceBlockingStub() {
ManagedChannel channel = ManagedChannelBuilder
.forTarget("localhost:9090")
.usePlaintext().build();
return EventServiceGrpc.newBlockingStub(channel);
}
}
< /code>
переработал службу клиентов в мой bin < /p>
...
public class EventService {
@Autowired
private EventServiceGrpc.EventServiceBlockingStub blockingStub;
public EventOuterClass.EventResponse getEventsByServiceName(String serviceName) {
EventOuterClass.EventsRequest request = EventOuterClass.EventsRequest
.newBuilder()
.setServiceName(serviceName)
.build();
EventOuterClass.EventResponse response = blockingStub.getEventsByServiceName(request).next();
return response;
}
...// here is the call to saveEvents
}
< /code>
Кроме того, моя заглушка имеет другую структуру, чем grpcclient < /p>
grpcclient Struftra Здесь "src =" https://i.sstatic.net/j1nfrn2c.png "/>
моя структура Blockstub
Если у меня недостаточно информации, напишу мне, я дополню свой вопрос.
Я пробовал разные версии зависимостей. А также вместо реализации grpcclient я сделал свой собственный, что работает.
Подробнее здесь: https://stackoverflow.com/questions/793 ... oesnt-work
Мобильная версия