2016-05-09 3 views
1

У меня есть требование, чтобы мои микросервисы использовали два способа ssl. Каждый microservice является Спринг загрузки приложений, аннотируются:FeignClient с сертификатом клиента и докером

@SpringBootApplication 
@EnableFeignClients 
@EnableDiscoveryClient 
@EnableZuulProxy 
public class Application { 
    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

Каждый имеет аналогичную YML конфигурацию для эврика/ленты:

eureka: 
    client: 
     service-url: 
      defaultZone: ${EUREKA_CLIENT_SERVICEURL_PROTOCOL:http}://${EUREKA_CLIENT_SERVICEURL_HOST:192.168.99.100}:${EUREKA_CLIENT_SERVICEURL_PORT:8761}/eureka/ 
    instance: 
     secure-virtual-host-name: ${spring.application.name} 
     prefer-ip-address: true 
     non-secure-port-enabled: ${EUREKA_NON_SECURE_PORT_ENABLED:false} 
     secure-port-enabled: ${EUREKA_SECURE_PORT_ENABLED:true} 
     secure-port: ${server.port} 
ribbon: 
    IsSecure: true 
    eureka: 
     enabled: true 

Каждый microservice имеет контроллер, который выставляет API отдыха для различных функциональных возможностей.

Когда один microservices нужно вызвать на другой microservice конечной точки, я пытаюсь сделать это путем создания клиентского интерфейса для этой microservice:

@FeignClient(name = "user", configuration = FeignConfiguration.class, url = "https://user") 
public interface UserClient { 
    @RequestMapping(method = RequestMethod.GET, value = "/test") 
    String testUser(); 
} 

Вот FeignConfiguration:

@Configuration 
public class FeignConfiguration { 

    @Bean 
    public Feign.Builder feignBuilder(){ 
     Client trustSSLSockets = new Client.Default(TrustingSSLSocketFactory.get(), null); 
     return Feign.builder().client(trustSSLSockets); 
    } 

    @Bean 
    Logger.Level feignLoggerLevel() { 
     return Logger.Level.FULL; 
    } 

    @Bean 
    public Contract feignContract() { 
     return new feign.Contract.Default(); 
    } 

} 

Класс TrustingSSLSocketFactory был скопирован с: https://github.com/Netflix/feign/blob/master/core/src/test/java/feign/client/TrustingSSLSocketFactory.java и изменен моим сертификатом/паролем клиента.

microservice пользователя, среди других конфигов, имеет безопасности настроен как:

server: 
    port: ${DOCKER_SERVER_PORT:28443} 
     ssl: 
      key-store: ${KEYSTORE_FILE:classpath:keystore.p12} 
      key-store-password: ${KEYSTORE_PASSWORD:abc123} 
      key-store-type: ${KEYSTORE_TYPE:PKCS12} 
      trust-store: ${TRUSTSTORE_FILE:classpath:trust.jks} 
      trust-store-password: ${TRUSTSTORE_PASSWORD:abc123} 
      trust-store-type: ${TRUSTSTORE_TYPE:JKS} 
      client-auth: ${CLIENT_AUTH_REQUIRED:want} 

Для вызова клиента, я просто впрыснуть клиента, и назовите его, как и любой другой интерфейс.

@RestController 
public class MyController { 

@Autowired 
UserClient userClient; 

@RequestMapping(value = "/testUser", 
     method = RequestMethod.GET, 
     produces = MediaType.APPLICATION_JSON_VALUE) 
    public String testUser() { 
     return userClient.testUser(); 
    } 
} 

Пользовательский микросервис имеет конечную точку тестирования, которая возвращает простой ответ.

Я получаю сообщение UnknownHostException, когда UserClient пытается установить соединение с хостом пользователя. Я, вероятно, не буду это делать правильно и буду признателен за некоторые рекомендации.

gateway-ms_1 | 2016-05-09 16:22:19.294 DEBUG 1 --- [qtp351251459-24]  c.n.zuul.http.HttpServletRequestWrapper : Path = null 
gateway-ms_1 | 2016-05-09 16:22:19.294 DEBUG 1 --- [qtp351251459-24] c.n.zuul.http.HttpServletRequestWrapper : Transfer-Encoding = null 
gateway-ms_1 | 2016-05-09 16:22:19.294 DEBUG 1 --- [qtp351251459-24] c.n.zuul.http.HttpServletRequestWrapper : Content-Encoding = null 
gateway-ms_1 | 2016-05-09 16:22:19.295 DEBUG 1 --- [qtp351251459-24] c.n.zuul.http.HttpServletRequestWrapper : Content-Length header = -1 
gateway-ms_1 | 2016-05-09 16:22:19.297 DEBUG 1 --- [qtp351251459-24] c.n.loadbalancer.ZoneAwareLoadBalancer : Zone aware logic disabled or there is only one zone 
gateway-ms_1 | 2016-05-09 16:22:19.298 DEBUG 1 --- [qtp351251459-24] c.n.loadbalancer.LoadBalancerContext  : register using LB returned Server: 172.17.0.4:28443 for request /testUser 
gateway-ms_1 | 2016-05-09 16:22:19.298 DEBUG 1 --- [qtp351251459-24] com.netflix.niws.client.http.RestClient : RestClient sending new Request(GET:) https://172.17.0.4:28443/testUser 
gateway-ms_1 | 2016-05-09 16:22:19.300 DEBUG 1 --- [qtp351251459-24] c.n.http4.MonitoredConnectionManager  : Get connection: {s}->https://172.17.0.4:28443, timeout = 3000 
gateway-ms_1 | 2016-05-09 16:22:19.300 DEBUG 1 --- [qtp351251459-24] com.netflix.http4.NamedConnectionPool : [{s}->https://172.17.0.4:28443] total kept alive: 1, total issued: 0, total allocated: 1 out of 200 
gateway-ms_1 | 2016-05-09 16:22:19.300 DEBUG 1 --- [qtp351251459-24] com.netflix.http4.NamedConnectionPool : Getting free connection [{s}->https://172.17.0.4:28443][null] 
gateway-ms_1 | 2016-05-09 16:22:19.300 DEBUG 1 --- [qtp351251459-24] com.netflix.http4.NFHttpClient   : Stale connection check 
gateway-ms_1 | 2016-05-09 16:22:19.305 DEBUG 1 --- [qtp351251459-24] com.netflix.http4.NFHttpClient   : Attempt 1 to execute request 
register-ms_1 | 2016-05-09 16:22:19.312 DEBUG 1 --- [qtp376795121-24] com.jdh.register.clients.UserClient  : [UserClient#testUser] ---> GET https://user/test HTTP/1.1 
register-ms_1 | 2016-05-09 16:22:19.313 DEBUG 1 --- [qtp376795121-24] com.jdh.register.clients.UserClient  : [UserClient#testUser] ---> END HTTP (0-byte body) 
register-ms_1 | 2016-05-09 16:22:19.422 DEBUG 1 --- [qtp376795121-24] com.jdh.register.clients.UserClient  : [UserClient#testUser] <--- ERROR UnknownHostException: user (109ms) 
register-ms_1 | 2016-05-09 16:22:19.426 DEBUG 1 --- [qtp376795121-24] com.jdh.register.clients.UserClient  : [UserClient#testUser] java.net.UnknownHostException: user 
register-ms_1 | at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184) 
register-ms_1 | at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) 
register-ms_1 | at java.net.Socket.connect(Socket.java:589) 
register-ms_1 | at sun.net.NetworkClient.doConnect(NetworkClient.java:175) 
register-ms_1 | at sun.net.www.http.HttpClient.openServer(HttpClient.java:432) 
register-ms_1 | at sun.net.www.http.HttpClient.openServer(HttpClient.java:527) 
register-ms_1 | at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:275) 
register-ms_1 | at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:371) 
register-ms_1 | at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191) 
register-ms_1 | at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1104) 
register-ms_1 | at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:998) 
register-ms_1 | at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177) 
register-ms_1 | at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1512) 
evice-ms_1 |  at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440) 

ответ

2

Примером Client является место, где вводится лента. Создав свой собственный клиент, вы отказались от ленты, поэтому http://user/... не разрешается лентой.

Это, как мы создаем балансировку нагрузки клиент

@Bean 
@ConditionalOnMissingBean 
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, 
     SpringClientFactory clientFactory) { 
    return new LoadBalancerFeignClient(new Client.Default(null, null), 
      cachingFactory, clientFactory); 
} 

Кроме того, с помощью feign.Contract.Default() вы отказаться от использования Spring MVC аннотаций, как @RequestMapping и по умолчанию, чтобы симулировать аннотации.

Смежные вопросы