Springboot将HTTPS请求作为客户端发送到Consul

springboot send https request as client to consul

提问人:superDu 提问时间:11/12/2023 更新时间:11/12/2023 访问量:35

问:

我正在尝试通过https将我的springboot服务注册到consul。现在我唯一拥有的是一个认证文件:ca-cert.pem。我相信这就是我所需要的,因为我可以使用它来使用 nodejs 连接到领事。我的appliation.yml如下:

server:
  port: 4242

spring:
  application:
    name: spring-consul-test
  cloud:
    consul:
      host: consul-consul-server
      port: 8501
      enabled: true
      config:
        enabled: true
        format: YAML
        acl-token: *****

      discovery:
        register: true
        health-check-path: /actuator/health
        health-check-interval: 10s
        instance-id: ${spring.application.name}:${server.port}
        enabled: true
        service-name: ${spring.application.name}
        ip-address: localhost
        prefer-ip-address: true
        scheme: https

consul:
  ssl:
    ca-cert: classpath:ca-cert.pem

WebClientConfig.java:

package com.example.springconsultest;



import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;

import java.io.File;

@Configuration
public class WebClientConfig {
    @Bean
    public WebClient.Builder webClientBuilder() throws Exception {
        SslContext sslContext = SslContextBuilder.forClient()
                .trustManager(getClass().getResourceAsStream("ca-cert.pem"))
                .build();

        HttpClient httpClient = HttpClient.create()
                .secure(t -> t.sslContext(sslContext));

        return WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient));
    }
}

ConsulService.java:

package com.example.springconsultest;


import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

@Service
public class ConsulService {
    private final WebClient.Builder webClientBuilder;

    public ConsulService(WebClient.Builder webClientBuilder) {
        this.webClientBuilder = webClientBuilder;
    }

    public String getConsulData() {
        String result = webClientBuilder.build()
                .get()
                .uri("https://consul-consul-server:8501")
                .retrieve()
                .bodyToMono(String.class)
                .block();
        return result;
    }
}

TestController:

package com.example.springconsultest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@RestController
public class TestController {
    @GetMapping("/time")
    public ResponseEntity<String> getCurrentTime() {
        String time = new Date().toString();
        return new ResponseEntity<>("Spring service: " + time, HttpStatus.OK);
    }

    @Autowired
    ConsulService consulService;
    @GetMapping("consulTest")
    public ResponseEntity<String> consulTest() {
        String result = consulService.getConsulData();
        return new ResponseEntity<>(result, HttpStatus.OK);
    }
}

但是,当我运行它时,它显示如下错误:

kubectl logs spring-consul-test-78c8cc755-twtn8 

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v2.2.13.RELEASE)

2023-11-10 06:08:11.691  INFO 1 --- [           main] c.e.s.SpringConsulTestApplication        : No active profile set, falling back to default profiles: default
2023-11-10 06:08:12.421  WARN 1 --- [           main] o.s.boot.actuate.endpoint.EndpointId     : Endpoint ID 'service-registry' contains invalid characters, please migrate to a valid format.
2023-11-10 06:08:12.531  INFO 1 --- [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=c9a87b20-5327-3433-9b8d-f53afb1cade4
2023-11-10 06:08:12.643  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration' of type [org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-11-10 06:08:12.644  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration$ReactiveLoadBalancerConfig' of type [org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration$ReactiveLoadBalancerConfig] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-11-10 06:08:12.646  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'deferringLoadBalancerExchangeFilterFunction' of type [org.springframework.cloud.client.loadbalancer.reactive.DeferringLoadBalancerExchangeFilterFunction] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2023-11-10 06:08:12.895  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 4242 (http)
2023-11-10 06:08:12.907  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-11-10 06:08:12.907  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.41]
2023-11-10 06:08:12.958  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-11-10 06:08:12.958  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1246 ms
2023-11-10 06:08:13.059  WARN 1 --- [           main] c.n.c.sources.URLConfigurationSource     : No URLs will be polled as dynamic configuration sources.
2023-11-10 06:08:13.059  INFO 1 --- [           main] c.n.c.sources.URLConfigurationSource     : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2023-11-10 06:08:13.133  INFO 1 --- [           main] c.netflix.config.DynamicPropertyFactory  : DynamicPropertyFactory is initialized with configuration sources: com.netflix.config.ConcurrentCompositeConfiguration@5e3f861
2023-11-10 06:08:13.408  WARN 1 --- [           main] c.n.c.sources.URLConfigurationSource     : No URLs will be polled as dynamic configuration sources.
2023-11-10 06:08:13.408  INFO 1 --- [           main] c.n.c.sources.URLConfigurationSource     : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2023-11-10 06:08:13.641  INFO 1 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2023-11-10 06:08:14.161  WARN 1 --- [           main] ockingLoadBalancerClientRibbonWarnLogger : You already have RibbonLoadBalancerClient on your classpath. It will be used by default. As Spring Cloud Ribbon is in maintenance mode. We recommend switching to BlockingLoadBalancerClient instead. In order to use it, set the value of `spring.cloud.loadbalancer.ribbon.enabled` to `false` or remove spring-cloud-starter-netflix-ribbon from your project.
2023-11-10 06:08:14.171  WARN 1 --- [           main] eactorLoadBalancerClientRibbonWarnLogger : You have RibbonLoadBalancerClient on your classpath. LoadBalancerExchangeFilterFunction that uses it under the hood will be used by default. Spring Cloud Ribbon is now in maintenance mode, so we suggest switching to ReactorLoadBalancerExchangeFilterFunction instead. In order to use it, set the value of `spring.cloud.loadbalancer.ribbon.enabled` to `false` or remove spring-cloud-starter-netflix-ribbon from your project.
2023-11-10 06:08:14.214  INFO 1 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService 'catalogWatchTaskScheduler'
2023-11-10 06:08:14.225  INFO 1 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2023-11-10 06:08:14.279  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 4242 (http) with context path ''
2023-11-10 06:08:14.310  INFO 1 --- [           main] o.s.c.c.s.ConsulServiceRegistry          : Registering service with consul: NewService{id='spring-consul-test-4242', name='spring-consul-test', tags=[secure=true], address='localhost', meta={}, port=4242, enableTagOverride=null, check=Check{script='null', dockerContainerID='null', shell='null', interval='10s', ttl='null', http='https://localhost:4242/actuator/health', method='null', header={}, tcp='null', timeout='null', deregisterCriticalServiceAfter='null', tlsSkipVerify=null, status='null', grpc='null', grpcUseTLS=null}, checks=null}
2023-11-10 06:08:14.315 ERROR 1 --- [TaskScheduler-1] o.s.c.c.discovery.ConsulDiscoveryClient  : Error watching Consul CatalogServices

com.ecwid.consul.v1.OperationException: OperationException(statusCode=400, statusMessage='Bad Request', statusContent='Client sent an HTTP request to an HTTPS server.
')
        at com.ecwid.consul.v1.catalog.CatalogConsulClient.getCatalogServices(CatalogConsulClient.java:151) ~[consul-api-1.4.5.jar!/:na]
        at com.ecwid.consul.v1.ConsulClient.getCatalogServices(ConsulClient.java:400) ~[consul-api-1.4.5.jar!/:na]
        at org.springframework.cloud.consul.discovery.ConsulCatalogWatch.catalogServicesWatch(ConsulCatalogWatch.java:135) ~[spring-cloud-consul-discovery-2.2.8.RELEASE.jar!/:2.2.8.RELEASE]
        at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_342]
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) ~[na:1.8.0_342]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_342]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) ~[na:1.8.0_342]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_342]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_342]
        at java.lang.Thread.run(Thread.java:750) ~[na:1.8.0_342]

2023-11-10 06:08:14.323 ERROR 1 --- [           main] o.s.c.c.s.ConsulServiceRegistry          : Error registering service with consul: NewService{id='spring-consul-test-4242', name='spring-consul-test', tags=[secure=true], address='localhost', meta={}, port=4242, enableTagOverride=null, check=Check{script='null', dockerContainerID='null', shell='null', interval='10s', ttl='null', http='https://localhost:4242/actuator/health', method='null', header={}, tcp='null', timeout='null', deregisterCriticalServiceAfter='null', tlsSkipVerify=null, status='null', grpc='null', grpcUseTLS=null}, checks=null}

com.ecwid.consul.v1.OperationException: OperationException(statusCode=400, statusMessage='Bad Request', statusContent='Client sent an HTTP request to an HTTPS server.
')
        at com.ecwid.consul.v1.agent.AgentConsulClient.agentServiceRegister(AgentConsulClient.java:278) ~[consul-api-1.4.5.jar!/:na]
        at com.ecwid.consul.v1.ConsulClient.agentServiceRegister(ConsulClient.java:310) ~[consul-api-1.4.5.jar!/:na]
        at org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry.register(ConsulServiceRegistry.java:68) [spring-cloud-consul-discovery-2.2.8.RELEASE.jar!/:2.2.8.RELEASE]
        at org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry.register(ConsulServiceRegistry.java:43) [spring-cloud-consul-discovery-2.2.8.RELEASE.jar!/:2.2.8.RELEASE]
        at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.register(AbstractAutoServiceRegistration.java:239) [spring-cloud-commons-2.2.9.RELEASE.jar!/:2.2.9.RELEASE]
        at org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistration.register(ConsulAutoServiceRegistration.java:83) [spring-cloud-consul-discovery-2.2.8.RELEASE.jar!/:2.2.8.RELEASE]
        at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.start(AbstractAutoServiceRegistration.java:138) [spring-cloud-commons-2.2.9.RELEASE.jar!/:2.2.9.RELEASE]
        at org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistration.start(ConsulAutoServiceRegistration.java:73) [spring-cloud-consul-discovery-2.2.8.RELEASE.jar!/:2.2.8.RELEASE]
        at org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationListener.onApplicationEvent(ConsulAutoServiceRegistrationListener.java:63) [spring-cloud-consul-discovery-2.2.8.RELEASE.jar!/:2.2.8.RELEASE]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) [spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) [spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) [spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404) [spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361) [spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:165) [spring-boot-2.2.13.RELEASE.jar!/:2.2.13.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554) [spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) [spring-boot-2.2.13.RELEASE.jar!/:2.2.13.RELEASE]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.13.RELEASE.jar!/:2.2.13.RELEASE]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:405) [spring-boot-2.2.13.RELEASE.jar!/:2.2.13.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.13.RELEASE.jar!/:2.2.13.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.13.RELEASE.jar!/:2.2.13.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.13.RELEASE.jar!/:2.2.13.RELEASE]
        at com.example.springconsultest.SpringConsulTestApplication.main(SpringConsulTestApplication.java:13) [classes!/:0.0.1-SNAPSHOT]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_342]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_342]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_342]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_342]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [app.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [app.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:51) [app.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52) [app.jar:0.0.1-SNAPSHOT]

我花了两天时间寻找解决方案。我尝试使用密钥库或信任库等 ssl 属性在 application.yml 中设置服务器字段。但我没有私钥。而且我确定我不需要它,因为我的springboot服务仅用作客户端向服务器发送请求,而不是像https服务器那样工作。

有人可以帮忙吗?非常感谢!!

Spring spring-Boot https 领事

评论


答: 暂无答案