Недавно я работал над проектом шлюза API. Однако для реестра и обнаружения служб я столкнулся с некоторыми проблемами, связанными с отказоустойчивостью Zuul и динамическим развертыванием нескольких экземпляров Eureka. Следующее - мой проект.
проект сервера eureka
EurekaBootstrap.java
package com.plateno.cloud.netflix.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaBootstrap {
public static void main(String[] args) {
SpringApplication.run(EurekaBootstrap.class, args);
}
}
config: application.yml
#spring.application.name=plateno-cloud-netflix-eureka
#server.port=9000
#eureka.instance.hostname=localhost
#eureka.client.registerWithEureka=false
#eureka.client.fetchRegistry=false
#eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
#spring.profiles.active: dev
server:
port: 9000
spring.application.name: localhost
eureka:
client:
serviceUrl:
defaultZone: http://localhost:${server.port}/eureka/
instance:
hostname: localhost
eureka.client.register-with-eureka: false
eureka.client.fetch-registry: false
---
spring:
profiles: peer1
server:
port: 9001
peer2:
port: 9002
spring.application.name: peer1
eureka:
client:
serviceUrl:
defaultZone: http://peer2:${peer2.port}/eureka/
instance:
hostname: peer1
eureka.client.register-with-eureka: true
eureka.client.fetch-registry: true
---
spring:
profiles: peer2
server:
port: 9002
spring.application.name: peer2
peer1:
port: 9001
eureka:
client:
serviceUrl:
defaultZone: http://peer1:${peer1.port}/eureka/
instance:
hostname: peer2
eureka.client.register-with-eureka: true
eureka.client.fetch-registry: true
---
spring:
profiles:
active: peer1
Я настроил peer1 и peer2 на localhost на хосте
проект zuul с лентой
ZuulBootstrap.java
package com.plateno.cloud.netflix.zuul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapper;
import org.springframework.context.annotation.Bean;
import com.netflix.zuul.exception.ZuulException;
@SpringBootApplication
@EnableZuulProxy
public class ZuulBootstrap {
public static void main(String[] args) {
SpringApplication.run(ZuulBootstrap.class, args);
}
@Bean
public SimpleFilter simpleFilter() {
return new SimpleFilter();
}
@Bean
public PatternServiceRouteMapper serviceRouteMapper() {
return new PatternServiceRouteMapper("(?<name>^.+)", "${name}") {
@Override
public String apply(final String serviceId) {
String route = super.apply(serviceId);
return route;
}
};
}
@RefreshScope
@ConfigurationProperties("zuul")
public ZuulProperties zuulProperties() {
ZuulProperties zuulProperties = new ZuulProperties();
return zuulProperties;
}
}
Предварительный фильтр: SimpleFilter.java
package com.plateno.cloud.netflix.zuul;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
public class SimpleFilter extends ZuulFilter {
private static Logger log = LoggerFactory.getLogger(SimpleFilter.class);
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
return null;
}
}
zuul config: application.yml
#default_charset=utf-8
#spring.application.name=plateno-cloud-netflix-zuul
#server.port=9030
#ribbon.eureka.enabled=true
#eureka.client.serviceUrl.defaultZone=http\://localhost\:9001/eureka/
---
default_charset: utf-8
spring:
application:
name: plateno-cloud-netflix-zuul
server:
port: 9030
ribbon:
eureka:
enabled: true
eureka:
client:
service-url:
defaultZone: http://localhost:9001/eureka/,http://localhost:9002/eureka/
целевой сервисный проект обычный проект с конфигурацией yml
Я не разбирал исходный код этого проекта, но профиль конфигурации
#default_charset=utf-8
#spring.application.name=plateno-app0
#server.port=9010
#eureka.client.serviceUrl.defaultZone=http\://localhost\:9000/eureka/
server:
port: 8080
default_charset: utf-8
spring:
application:
name: plateno-app0
eureka.client.serviceUrl.defaultZone: http://peer1:9001/eureka/,http://peer2:9002/eureka/
конец источника, вложение - это исходный код
Я запустил 2 экземпляра eureka, изменив активный, затем я запустил сервер zuul. Наконец, я запустил две целевые службы, изменив порт сервера. Я провел несколько тестов с помощью JMeter. Я остановил одну целевую службу в середине теста параллелизма, затем некоторые запросы не прошли проверку на закрытие сокета.
Возникает вопрос, почему zuul и лента не смогли справиться с переключением при отказе или как мне настроить, чтобы достичь этого эффекта?
Второй вопрос: каждый раз, когда я развертываю другой сервер eureka, мне нужно редактировать конфигурацию сервера eureka, конфигурацию zuul и конфигурацию целевой службы. Поэтому все эти проекты необходимо перезапустить. Я не могу с этим согласиться, так есть ли способ динамически изменять количество серверов eureka без редактирования конфигурации других проектов и их перезапуска?
В конце концов, я надеюсь, что команда Pivotal сможет обновить документацию по весеннему облаку, чтобы предоставить более подробную информацию.