繁体   English   中英

Spring Cloud Kafka:连接被拒绝:没有更多信息

[英]Spring Cloud Kafka: Connection refused: no further information

我是 Kafka 的新手,正在努力解决这个烦人的问题:

这是我用 Postman 发送请求时遇到的异常

{ "timestamp": "2022-02-24T14:22:36.851+00:00", "status": 401, "error": "Unauthorized", "path": "/api/v1/customers/barbie" }

概念很简单:2 个应用程序分开 - 1 个充当生产者,1 个充当消费者,来回发送的 object 是“消息”。

这是生产者:“客户”

CustomerConfig:我使用 SOAP + Spring WS

@EnableWs
@Configuration
public class CustomerConfig extends WsConfigurerAdapter {
    @Bean
    public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);
        servlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean(servlet, "/ws/*");
    }

    @Bean(name = "customer")
    public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema customerSchema) {
        DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
        wsdl11Definition.setPortTypeName("CustomerPort");
        wsdl11Definition.setLocationUri("/ws");
        wsdl11Definition.setTargetNamespace("http://spring.io/guides/gs-producing-web-service");
        wsdl11Definition.setSchema(customerSchema);
        return wsdl11Definition;
    }

    @Bean
    public XsdSchema countriesSchema() {
        return new SimpleXsdSchema(new ClassPathResource("customer.xsd"));
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Bean public KafkaTemplate<String, Message> kafkaTemplate(ProducerFactory<String, Message> producerFactory) {
        return new KafkaTemplate(producerFactory);
    }

    @Bean
    public ProducerFactory<String, Message> producerFactory(KafkaProperties kafkaProperties) {
        Map<String, Object> configProps = new HashMap<>();
        configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
        configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
        configProps.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, 30000);
        return new DefaultKafkaProducerFactory(kafkaProperties.buildProducerProperties());
    }

    @Value("${spring.kafka.producer.bootstrap-servers}")
    private String bootstrapAddress;

    @Bean
    public KafkaAdmin kafkaAdmin() {
        Map<String, Object> configs = new HashMap<>();
        configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
        return new KafkaAdmin(configs);
    }

    /*
    @Bean
    public NewTopic processTopic() {
        return TopicBuilder.name("I´m a Barbie girl").partitions(2).build();
    }
     */
}

CustomerController:端点,位于 REST。为了测试。 真正的 SOAP Endpoint 同时被注释掉

    @Slf4j
    @RestController
    @RequestMapping("api/v1/customers")

public class CustomerController {
    @Autowired
    private CustomerService the_service;

    @GetMapping("/barbie")
    public String doSomething() {
        the_service.sendSomeBS();
        return "It works, how bad ass is that, bitches!!!";
    }
}

客户服务

@AllArgsConstructor
@Service("FeignImpl")
@Slf4j
public class CustomerService {

    @Autowired
    private KafkaTemplate<String, Message> kafkaTemplate;

    private final CustomerRepository customerRepository;

    private final MessageRepository messageRepository;

     public Customer findOneCustomer(String customerName) throws NotFoundException {

        return customerRepository.findCustomerByFirstName(customerName)
                .orElseThrow(
                        () -> new NotFoundException(String.format("User %s not found", customerName))
                );

     }

     public void sendSomeBS(){
        System.out.println("Afjasdgjkdhjkgsdfklgh");
        Message to_send = messageRepository.findMessageByMessageName("Bla").get();
        kafkaTemplate.send("Barbie", to_send);
     }
}

生产者应用程序的“application.yml”

server:
  port: 9090

spring:
  application:
    name: customer
  datasource:
    password: 
    url: jdbc:postgresql://localhost:5432/postgres
    username: 
  jpa:
    generate-ddl: true
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect
        format_sql: true
    show-sql: true
  kafka:
    producer:
      bootstrap-servers: localhost:9092
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
  instance:
    prefer-ip-address: true
    hostname: localhost

来回发送的“消息”object

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
public class Message {

    @Id
    private Integer id;

    private String something;

    private String messageName;
}

*** 消费者:“交易”

** 交易配置

@EnableWs
@Configuration
public class TransactionConfig {
    @Bean
    public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);
        servlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean(servlet, "/ws/*");
    }

    @Bean(name = "transaction")
    public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema transactionSchema) {
        DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
        wsdl11Definition.setPortTypeName("TransactionPort");
        wsdl11Definition.setLocationUri("/ws");
        wsdl11Definition.setTargetNamespace("http://spring.io/guides/gs-producing-web-service");
        wsdl11Definition.setSchema(transactionSchema);
        return wsdl11Definition;
    }

    @Bean
    public XsdSchema countriesSchema() {
        return new SimpleXsdSchema(new ClassPathResource("transaction.xsd"));
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Bean
    public ConsumerFactory<String, Message> consumerFactory(KafkaProperties kafkaProperties){
        Map<String, Object> configProps = new HashMap<>();
        configProps.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
        configProps.put(ConsumerConfig.GROUP_ID_CONFIG, "group_id");
        configProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        configProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
        configProps.put(JsonDeserializer.TRUSTED_PACKAGES, getClass().getName());
        return new DefaultKafkaConsumerFactory<>(kafkaProperties.buildConsumerProperties());
    }

    @Value("${spring.kafka.consumer.bootstrap-servers}")
    private String bootstrapAddress;

    @Bean
    public KafkaAdmin kafkaAdmin() {
        Map<String, Object> configs = new HashMap<>();
        configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
        return new KafkaAdmin(configs);
    }

    /*
    @Bean
    public NewTopic processTopic() {
        return TopicBuilder.name("I´m a Barbie girl").partitions(2).build();
    }
     */
}

** 交易服务

@AllArgsConstructor
@Service("FeignImpl")
@Slf4j
public class TransactionService {

    private final TransactionRepository transactionRepository;

    public Transaction findOneTransaction(String message) throws NotFoundException {
        return transactionRepository.findByMessage(message).orElseThrow(
                () -> new NotFoundException(String.format("Transaction with message %s not found", message))
        );
    }

    @KafkaListener(topics = "Barbie", groupId = "group_id")
    public void consume(Message message) {
        // Gut, gut
        System.out.println("Tasting Barbie " + message.getSomething());
    }
}

** 消费者的“application.yml”

server:
  port: 9095

spring:
  application:
    name: transaction
  datasource:
    password: 
    url: jdbc:postgresql://localhost:5432/postgres
    username: 
  jpa:
    generate-ddl: true
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect
        format_sql: true
    show-sql: true
  kafka:
    consumer:
      bootstrap-servers: localhost:9092
      group-id: group_id
      auto-offset-reset: earliest
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
      properties:
        spring.json.trusted.packages: "com.test.transaction"

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
  instance:
    prefer-ip-address: true
    hostname: localhost

这两个应用程序都通过 EurekaServer 连接,由 Gateway 在相同的 URL“localhost:9091”下发布。 只需要一个小的额外 header “SOAPAction” 来告诉网关哪个应用程序是目标。

该过程如下所示:调用 CustomerController 的“doSomething()”REST 端点来触发消息传递。

但不知何故我无法获得授权。

我究竟做错了什么?

这是我发送请求时我的“客户”的日志

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:9411/api/v2/spans": Connection refused: no further information; nested exception is java.net.ConnectException: Connection refused: no further information
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:785) ~[spring-web-5.3.13.jar:5.3.13]
    at org.springframework.cloud.sleuth.zipkin2.ZipkinRestTemplateWrapper.doExecute(ZipkinRestTemplateWrapper.java:69) ~[spring-cloud-sleuth-zipkin-3.0.3.jar:3.0.3]
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:660) ~[spring-web-5.3.13.jar:5.3.13]
    at org.springframework.cloud.sleuth.zipkin2.RestTemplateSender.post(RestTemplateSender.java:151) ~[spring-cloud-sleuth-zipkin-3.0.3.jar:3.0.3]
    at org.springframework.cloud.sleuth.zipkin2.RestTemplateSender$HttpPostCall.doExecute(RestTemplateSender.java:169) ~[spring-cloud-sleuth-zipkin-3.0.3.jar:3.0.3]
    at org.springframework.cloud.sleuth.zipkin2.RestTemplateSender$HttpPostCall.doExecute(RestTemplateSender.java:159) ~[spring-cloud-sleuth-zipkin-3.0.3.jar:3.0.3]
    at zipkin2.Call$Base.execute(Call.java:391) ~[zipkin-2.23.0.jar:na]
    at zipkin2.reporter.AsyncReporter$BoundedAsyncReporter.flush(AsyncReporter.java:299) ~[zipkin-reporter-2.16.1.jar:na]
    at zipkin2.reporter.AsyncReporter$Flusher.run(AsyncReporter.java:378) ~[zipkin-reporter-2.16.1.jar:na]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.net.ConnectException: Connection refused: no further information
    at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
    at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
    at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542) ~[na:na]
    at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597) ~[na:na]
    at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
    at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:178) ~[na:na]
    at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:498) ~[na:na]
    at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:603) ~[na:na]
    at java.base/sun.net.www.http.HttpClient.<init>(HttpClient.java:246) ~[na:na]
    at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:351) ~[na:na]
    at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:373) ~[na:na]
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1309) ~[na:na]
    at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1242) ~[na:na]
    at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1128) ~[na:na]
    at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1057) ~[na:na]
    at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:76) ~[spring-web-5.3.13.jar:5.3.13]
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-5.3.13.jar:5.3.13]
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66) ~[spring-web-5.3.13.jar:5.3.13]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:776) ~[spring-web-5.3.13.jar:5.3.13]
    ... 9 common frames omitted

:9411/api/v2/spans指的是 Zipkin 地址,可能是因为您在某处使用 Spring Cloud Sleuth。

如果您想删除这些日志,请禁用跟踪或在本地设置 Zipkin。

但是,这不应影响您的授权错误。 我认为这将源自 Eureka 服务器,因为您的 Spring 代码中似乎没有任何内容用于身份验证/授权

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM