20 mil millones de tráfico diario, diseño arquitectónico de la puerta de enlace Ctrip

lo dijo de frente

En la comunidad de lectores ( mayores de 50 años) del arquitecto Nien, de 40 años , muchos amigos han obtenido calificaciones para entrevistas de empresas de Internet de primer nivel como Alibaba, NetEase, Youzan, Xiyin, Baidu y Didi.

Ayer mismo, Nien guió el currículum de un amigo y escribió un " Proyecto Netty Gateway de alta concurrencia ". Este proyecto ayudó a este tipo a obtener una invitación a una entrevista de Byte/Alibaba/Weibo/Autohome, por lo que este es un proyecto increíble.

Para ayudarlo a obtener más oportunidades de entrevistas y más ofertas de grandes fabricantes, Nien decidió publicar un capítulo de video en septiembre para presentar la estructura y el funcionamiento práctico de este proyecto, que es el "Capítulo 33: Alta concurrencia de 10 Wqps" Netty Gateway. Se espera que Architecture and Practical Operation" se publique a finales de mes. También brindamos orientación personalizada sobre su currículum para garantizar que su currículum sea brillante y esté completamente transformado.

El cartel es el siguiente:

Junto con el vídeo de Nien, se clasificarán varias cajas de entrada de grado industrial y de producción como materiales arquitectónicos y de diseño.

Este artículo es el diseño arquitectónico de la puerta de enlace Ctrip. Es un caso de puerta de enlace de grado industrial y de producción impresionante .

20 mil millones de tráfico diario, diseño arquitectónico de la puerta de enlace Ctrip

El autor de la solución: Butters, un experto en tecnología de software de Ctrip que se centra en arquitectura de red, puerta de enlace API, equilibrio de carga, malla de servicios y otros campos.

Para obtener los archivos PDF de "Notas de arquitectura de Nien", "Trilogía de alta concurrencia de Nien" y " Guía de entrevistas de Java de Nien ", vaya a la cuenta oficial [Technical Freedom Circle] para obtener

I. Descripción general

De manera similar al enfoque de muchas empresas, Ctrip API Gateway es una infraestructura introducida junto con la arquitectura de microservicio, y su versión inicial se lanzó en 2014. Con el rápido avance de la servitización dentro de la empresa, las puertas de enlace se han convertido gradualmente en una solución estándar para que las aplicaciones estén expuestas a la red externa. En proyectos posteriores como "ALL IN Wireless", internacionalización y multiactividad en ubicaciones remotas, la pasarela ha seguido desarrollándose con la evolución común de los servicios públicos y las infraestructuras de la compañía. En julio de 2021, el número total de servicios de acceso supera los 3000 y el tráfico de procesamiento diario promedio alcanza los 20 mil millones.

En términos de soluciones técnicas, el desarrollo inicial de los microservicios de la compañía estuvo profundamente influenciado por NetflixOSS. La parte de la puerta de enlace se desarrolló por primera vez con referencia a Zuul 1.0. Su núcleo se puede resumir en los siguientes cuatro puntos:

  • servidor端:Tomcat NIO + AsyncServlet
  • Proceso de negocio: grupo de subprocesos independiente, modelo de cadena de responsabilidad por etapas
  • Lado del cliente: Apache HttpClient, llamada sincrónica
  • Componentes principales: Archaius (cliente de configuración dinámica), Hystrix (límite de corriente de fusible), Groovy (soporte de actualización en caliente)

NOTA: ¡Haga clic en la imagen para verla claramente!

Como todos sabemos, las llamadas sincrónicas bloquearán subprocesos y IO afectará en gran medida el rendimiento del sistema.

Como líder de la industria, Zuul ha tenido en cuenta este problema al diseñar: al introducir Hystrix, se logra el aislamiento de recursos y la limitación de corriente, y las fallas (IO lenta) se limitan a un cierto rango; combinado con la estrategia del disyuntor, algunos recursos de subprocesos se puede publicar con anticipación; en última instancia, el objetivo es lograr el objetivo de que las anomalías locales no afecten la situación general.

Sin embargo, con el continuo desarrollo del negocio de la empresa, el efecto de la estrategia anterior se ha debilitado gradualmente, principalmente por dos razones:

  • Negocios que van al extranjero: dado que la puerta de enlace sirve como capa de acceso al extranjero, parte del tráfico debe transferirse de regreso a China y la IO lenta se convierte en la norma.
  • Crecimiento en la escala del servicio: las excepciones locales se han convertido en la norma y, junto con la proliferación anormal de microservicios, el grupo de subprocesos puede estar en un estado deficiente durante mucho tiempo.

La transformación totalmente asincrónica ha sido un trabajo central de la puerta de enlace Ctrip API en los últimos años. Este artículo también se centrará en esto y discutirá nuestro trabajo y experiencia práctica en la puerta de enlace.

Los puntos clave incluyen: optimización del rendimiento, forma comercial, arquitectura técnica, experiencia en gobernanza, etc.

2. Diseño central de puerta de enlace de alto rendimiento

2.1 Diseño de procesos asincrónicos

Totalmente asíncrono = asíncrono del lado del servidor + asíncrono del proceso de negocio + asíncrono del lado del cliente

Para el servidor y el cliente, utilizamos el marco Netty, cuyo NIO/Epoll + Eventloop es esencialmente un diseño basado en eventos.

La parte central de nuestra transformación es asincrónicamente los procesos comerciales. Los escenarios asincrónicos comunes incluyen:

  • Eventos de IO empresarial: como verificación de solicitudes, autenticación de identidad, que involucran llamadas remotas
  • Eventos Self-IO: por ejemplo, se leen los primeros xx bytes del mensaje
  • Reenvío de solicitudes: incluida la conexión TCP, solicitud HTTP

Por experiencia, la programación asincrónica es un poco más difícil que la programación sincrónica en términos de diseño, lectura y escritura, e incluye principalmente:

  • Diseño de procesos y transición de estado.
  • Manejo de excepciones, incluidas excepciones generales y tiempos de espera
  • Entrega de contexto, incluido el contexto empresarial y el registro de seguimiento
  • Programación de hilos
  • control de flujo

Especialmente en el contexto de Netty, si el diseño del ciclo de vida de ByteBuf no es perfecto, fácilmente puede provocar pérdidas de memoria.

Centrándonos en estos problemas, diseñamos los marcos periféricos correspondientes e hicimos todo lo posible para suavizar las diferencias sincrónicas/asincrónicas en el código comercial para facilitar el desarrollo; al mismo tiempo, optamos por la seguridad y la tolerancia a fallas para garantizar la seguridad general del programa.

En términos de herramientas, utilizamos RxJava y su proceso principal se muestra en la siguiente figura.

NOTA: ¡Haga clic en la imagen para verla claramente!

  • Tal vez
    • La clase contenedora incorporada de RxJava representa tres estados: fin normal, uno y solo un objeto devuelto y excepción.
    • Responsivo, conveniente para el diseño general de la máquina de estado, con manejo de excepciones, tiempo de espera, programación de subprocesos y otros paquetes integrados
    • Maybe.empty()/Maybe.just(T), adecuado para escenarios de sincronización
    • Clase de herramienta RxJavaPlugins para facilitar la encapsulación de la lógica de aspectos
  • Filtrar
    • Representa una pieza independiente de lógica empresarial, una interfaz unificada para negocios sincrónicos y asincrónicos, y devuelve Quizás
    • Los escenarios asincrónicos (como llamadas remotas) se encapsulan uniformemente. Si se trata de un cambio de subproceso, vuelva a pasar por Maybe.obesrveOn (eventloop).
    • El filtro asincrónico aumenta el tiempo de espera de forma predeterminada, lo maneja como una dependencia débil e ignora los errores.
public interface Processor<T> {
    
        
    ProcessorType getType();
    
    int getOrder();
    
    boolean shouldProcess(RequestContext context);
    
    //对外统一封装为Maybe    
    Maybe<T> process(RequestContext context) throws Exception; 
}
public abstract class AbstractProcessor implements Processor {
    
     
    //同步&无响应,继承此方法 
    //场景:常规业务处理 
    protected void processSync(RequestContext context) throws Exception {
    
    }


    //同步&有响应,继承此方法,健康检测
    //场景:健康检测、未通过校验时的静态响应
    protected T processSyncAndGetReponse(RequestContext context) throws Exception {
    
    
        process(context);
        return null;
    };


    //异步,继承此方法
    //场景:认证、鉴权等涉及远程调用的模块
    protected Maybe<T> processAsync(RequestContext context) throws Exception 
    {
    
    
        T response = processSyncAndGetReponse(context);
        if (response == null) {
    
    
            return Maybe.empty();
        } else {
    
    
            return Maybe.just(response);
        }
    };


    @Override
    public Maybe<T> process(RequestContext context) throws Exception {
    
    
        Maybe<T> maybe = processAsync(context);
        if (maybe instanceof ScalarCallable) {
    
    
            //标识同步方法,无需额外封装
            return maybe;
        } else {
    
    
            //统一加超时,默认忽略错误
            return maybe.timeout(getAsyncTimeout(context), TimeUnit.MILLISECONDS,
                                 Schedulers.from(context.getEventloop()), timeoutFallback(context));
        }
    }


    protected long getAsyncTimeout(RequestContext context) {
    
    
        return 2000;
    }


    protected Maybe<T> timeoutFallback(RequestContext context) {
    
    
        return Maybe.empty();
    }
}
  • proceso general
    • Siguiendo el diseño de la cadena de responsabilidad, ésta se divide en cuatro etapas: entrante, saliente, error y registro.
    • Cada etapa consta de uno o más filtros.
    • Los filtros se ejecutan secuencialmente y se interrumpen cuando se encuentra una excepción. Durante el período de entrada, cualquier filtro que devuelva una respuesta también provocará una interrupción.
public class RxUtil{
    
    
    //组合某阶段(如Inbound)内的多个filter(即Callable<Maybe<T>>)
    public static <T> Maybe<T> concat(Iterable<? extends Callable<Maybe<T>>> iterable) {
    
    
        Iterator<? extends Callable<Maybe<T>>> sources = iterable.iterator();
        while (sources.hasNext()) {
    
    
            Maybe<T> maybe;
            try {
    
    
                maybe = sources.next().call();
            } catch (Exception e) {
    
    
                return Maybe.error(e);
            }
            if (maybe != null) {
    
    
                if (maybe instanceof ScalarCallable) {
    
    
                    //同步方法
                    T response = ((ScalarCallable<T>)maybe).call();
                    if (response != null) {
    
    
                        //有response,中断
                        return maybe;
                    }
                } else {
    
    
                    //异步方法
                    if (sources.hasNext()) {
    
    
                        //将sources传入回调,后续filter重复此逻辑
                        return new ConcattedMaybe(maybe, sources);
                    } else {
    
    
                        return maybe;
                    }
                }
            }
        }
        return Maybe.empty();
    }
}
public class ProcessEngine{
    
    
    //各个阶段,增加默认超时与错误处理
    private void process(RequestContext context) {
    
    
        List<Callable<Maybe<Response>>> inboundTask = get(ProcessorType.INBOUND, context);
        List<Callable<Maybe<Void>>> outboundTask = get(ProcessorType.OUTBOUND, context);
        List<Callable<Maybe<Response>>> errorTask = get(ProcessorType.ERROR, context);
        List<Callable<Maybe<Void>>> logTask = get(ProcessorType.LOG, context);

        RxUtil.concat(inboundTask)    //inbound阶段                    
            .toSingle()        //获取response                          
            .flatMapMaybe(response -> {
    
    
                context.setOriginResponse(response);
                return RxUtil.concat(outboundTask);
            })            //进入outbound
            .onErrorResumeNext(e -> {
    
    
                context.setThrowable(e);
                return RxUtil.concat(errorTask).flatMap(response -> {
    
    
                    context.resetResponse(response);
                    return RxUtil.concat(outboundTask);
                });
            })            //异常则进入error,并重新进入outbound
            .flatMap(response -> RxUtil.concat(logTask))  //日志阶段
            .timeout(asyncTimeout.get(), TimeUnit.MILLISECONDS, Schedulers.from(context.getEventloop()),
                     Maybe.error(new ServerException(500, "Async-Timeout-Processing"))
                    )            //全局兜底超时
            .subscribe(        //释放资源
            unused -> {
    
    
                logger.error("this should not happen, " + context);
                context.release();
            },
            e -> {
    
    
                logger.error("this should not happen, " + context, e);
                context.release();
            },
            () -> context.release()
        );
    }   
}

2.2 Reenvío de streaming y hilo único

Tomando HTTP como ejemplo, un mensaje se puede dividir en tres componentes: línea inicial/encabezado/cuerpo.

En Ctrip, el negocio de la capa de puerta de enlace no involucra el cuerpo de la solicitud.

Dado que no es necesario almacenar el monto total, puede ingresar directamente al proceso comercial después de analizar el encabezado de la solicitud.

Al mismo tiempo, si se recibe la parte del cuerpo del cuerpo de la solicitud:

①Si la solicitud se ha enviado a aguas arriba, reenvíela directamente;

② De lo contrario, debe almacenarse temporalmente y luego enviarse junto con la línea/encabezado inicial una vez que se complete el proceso comercial;

③Lo mismo ocurre con la respuesta ascendente.

En comparación con la forma de analizar completamente el mensaje HTTP, se procesa así:

  • Ingresar antes al proceso de negocios significa que el flujo ascendente recibe la solicitud antes, lo que puede reducir efectivamente el retraso introducido por la capa de puerta de enlace.
  • El ciclo de vida del cuerpo está comprimido, lo que puede reducir la sobrecarga de memoria de la propia puerta de enlace.

A pesar de las mejoras de rendimiento, la transmisión también aumenta significativamente la complejidad del proceso general.

NOTA: ¡Haga clic en la imagen para verla claramente!

En escenarios sin transmisión, los subprocesos de codificación y decodificación del lado del servidor Netty, la lógica empresarial entrante, la codificación y decodificación del lado del cliente Netty y la lógica empresarial saliente son independientes entre sí y cada proceso es un objeto HTTP completo. Con el procesamiento de streaming, las solicitudes pueden estar en múltiples procesos al mismo tiempo, lo que plantea los siguientes tres desafíos:

  • Problemas de seguridad de subprocesos: si cada proceso utiliza subprocesos diferentes, puede estar involucrada una modificación simultánea del contexto;
  • Enlace de varias etapas: por ejemplo, si Netty Server encuentra una interrupción de la conexión a la mitad de la recepción de una solicitud y ya está conectado al flujo ascendente, entonces la pila de protocolos en el lado ascendente no se completará y la conexión debe cerrarse en consecuencia;
  • Procesamiento de escena perimetral: por ejemplo, si el flujo ascendente devuelve 404/413 cuando la solicitud no se envía por completo, debe optar por continuar enviando, completar la pila de protocolos y permitir que se reutilice la conexión, o debe optar por finalizar el proceso antes de tiempo. ¿Ahorrar recursos pero renunciar a la conexión al mismo tiempo? Para otro ejemplo, upstream recibió la solicitud pero no respondió. En este momento, el servidor Netty se desconecta repentinamente. ¿Se desconectará también el cliente Netty? etc.

Para hacer frente a estos desafíos, adoptamos un enfoque de subproceso único. El diseño central incluye:

  • El documento en línea está vinculado a Eventloop, y Netty Server/Business Process/Netty Client se ejecutan en el mismo eventloop;
  • Si el filtro asíncrono debe utilizar un grupo de subprocesos independiente debido a la biblioteca IO, entonces se debe volver a cambiar el posprocesamiento;
  • Realice el aislamiento de subprocesos necesario para los recursos del proceso (como el grupo de conexiones);

El método de un solo subproceso evita problemas de concurrencia. Cuando se trata de enlaces de múltiples etapas y problemas de escena perimetral, todo el sistema está en un cierto estado, lo que reduce efectivamente la dificultad y los riesgos del desarrollo. Además, reducir el cambio de subprocesos también puede mejorar el rendimiento a un cierto punto. Sin embargo, debido a la pequeña cantidad de subprocesos de trabajo (generalmente igual a la cantidad de núcleos de CPU), las operaciones de IO deben evitarse por completo en el bucle de eventos; de lo contrario, tendrá un impacto significativo en el rendimiento del sistema.

2.3 Otras optimizaciones

  • Carga diferida de variables internas

Para las cookies/consultas solicitadas y otros campos, el análisis de cadenas no se realizará por adelantado si no es necesario.

  • Memoria fuera del montón y copia cero

Combinado con el diseño de reenvío de transmisión anterior, el uso de la memoria del sistema se reduce aún más.

  • ZGC

Desde que el proyecto se actualizó a TLSv1.3, se introdujo JDK11 (la compatibilidad con JDK8 es tardía, versión 8u261, 2020.7.14) y también se probó una nueva generación de algoritmo de recolección de basura. Su rendimiento real es tan bueno como la gente esperaba. Aunque el uso de la CPU ha aumentado, el tiempo total de GC se ha reducido significativamente.

NOTA: ¡Haga clic en la imagen para verla claramente!

  • Códec HTTP personalizado

Debido a la larga historia y la apertura del protocolo HTTP, han surgido muchas "malas prácticas" que al menos afectan la tasa de éxito de las solicitudes y, en el peor de los casos, representan una amenaza para la seguridad del sitio web.

  • La gestión del tráfico

Para problemas como el cuerpo de la solicitud es demasiado grande (413), el URI es demasiado largo (414) y caracteres no ASCII (400), los servidores web generales optarán por rechazar directamente y devolver el código de estado correspondiente. Dado que este tipo de problema omite el proceso comercial, causará algunos problemas en términos de estadísticas, ubicación del servicio y resolución de problemas. Al extender el códec, las solicitudes problemáticas también pueden completar el proceso de enrutamiento, lo que ayuda a resolver el problema de gestión del tráfico no estándar.

  • Solicitar filtrado

Por ejemplo, contrabando de solicitudes (corregido por Netty 4.1.61.Final, publicado el 30 de marzo de 2021). Al ampliar el códec y agregar una lógica de verificación personalizada, los parches de seguridad se pueden aplicar más rápido.

3. Formulario comercial de puerta de enlace

Como punto de entrada independiente y unificado para el tráfico entrante, el valor de la puerta de enlace para las empresas se demuestra principalmente en tres aspectos:

  • Desacoplamiento de diferentes entornos de red: los escenarios típicos incluyen intranet y red externa, entorno de producción y área de oficina, diferentes dominios de seguridad dentro de IDC, líneas dedicadas, etc.;
  • Aspectos comerciales públicos naturales: incluida la seguridad, autenticación y anti-escalada, enrutamiento y escala de grises, limitación de corriente, disyuntor y degradación, monitoreo, alarma y resolución de problemas, etc.;

NOTA: ¡Haga clic en la imagen para verla claramente!

  • Control de flujo eficiente y flexible

Aquí hay algunos escenarios subdivididos:

  • protocolo privado

En el cliente cerrado (APP), la capa de marco interceptará la solicitud HTTP iniciada por el usuario y la transmitirá al servidor a través de un protocolo privado (SOTP).

En términos de selección de ubicación: ① asigne IP a través del servidor para evitar el secuestro de DNS; ② precaliente la conexión; ③ adopte una estrategia de selección de ubicación personalizada, que se puede cambiar automáticamente según las condiciones de la red, el entorno y otros factores.

En términos de modo de interacción: ① Utilice un cuerpo de protocolo más liviano; ② Cifre, comprima y multiplexe de manera unificada; ③ La puerta de enlace convierte uniformemente el protocolo en la entrada, lo que no tiene ningún impacto en el negocio.

  • Optimización de enlaces

La clave es introducir la capa de acceso para permitir que los usuarios remotos accedan a las zonas cercanas y resolver el problema de la sobrecarga excesiva del protocolo de enlace. Al mismo tiempo, dado que ambos extremos de la capa de acceso y el IDC son controlables, existe un mayor margen de optimización en términos de selección de enlaces de red y modo de interacción del protocolo.

  • Vive más en un lugar diferente

A diferencia de la asignación proporcional y las políticas de acceso cercano, en el modo multiactivo remoto, la puerta de enlace (capa de acceso) necesita desviar el tráfico de acuerdo con la clave de fragmentación de la dimensión empresarial (como el ID de usuario) para evitar conflictos de datos subyacentes.

NOTA: ¡Haga clic en la imagen para verla claramente!

4. Gestión de puerta de enlace

El diagrama que se muestra a continuación resume el estado de funcionamiento del portal en línea. Corresponde verticalmente a nuestro proceso comercial: el tráfico de varios canales (como APP, H5, mini programas, proveedores) y varios protocolos (como HTTP, SOTP) se distribuye a la puerta de enlace a través del equilibrio de carga y se procesa a través de una serie de procesos comerciales. lógica se reenvía al servicio backend. Después de las mejoras del Capítulo 2, el negocio horizontal ha mejorado significativamente en términos de rendimiento y estabilidad.

NOTA: ¡Haga clic en la imagen para verla claramente!

Por otro lado, debido a la existencia de múltiples canales/protocolos, los portales en línea se implementan en grupos independientes según el negocio. Al principio, las diferencias comerciales (como datos de enrutamiento y módulos funcionales) se gestionaban a través de ramas de código independientes, pero a medida que aumentaba el número de ramas, la complejidad de la operación y el mantenimiento generales también seguía aumentando. En el diseño de sistemas, la complejidad a menudo también significa riesgo. Por lo tanto, cómo gestionar de manera uniforme puertas de enlace multiprotocolo y múltiples funciones y cómo construir rápidamente puertas de enlace personalizadas para nuevos servicios a un costo menor se han convertido en el foco de nuestra siguiente fase de trabajo.

La solución se presenta intuitivamente en la figura: la primera es realizar un procesamiento de compatibilidad en el protocolo para que el código en línea pueda ejecutarse bajo un marco, la segunda es introducir un plano de control para gestionar de manera uniforme las diferentes características de la puerta de enlace en línea.

4.1 Compatibilidad multiprotocolo

El método de compatibilidad multiprotocolo no es nuevo: puede consultar el procesamiento abstracto de Tomcat de HTTP/1.0, HTTP/1.1 y HTTP/2.0. Aunque HTTP ha agregado muchas características nuevas en cada versión, generalmente no podemos percibir estos cambios cuando realizamos desarrollo empresarial. La clave está en la abstracción de la interfaz HttpServletRequest.

En Ctrip, la puerta de enlace en línea maneja protocolos sin estado en modo solicitud-respuesta. La estructura del mensaje también se puede dividir en tres partes: metadatos, encabezado de extensión y mensaje comercial, por lo que se pueden realizar fácilmente intentos similares. El trabajo relacionado se puede resumir en los dos puntos siguientes:

  • Capa de adaptación de protocolo: se utiliza para proteger la codificación y decodificación de diferentes protocolos, modos interactivos, procesamiento de conexiones TCP, etc.
  • Definir modelos e interfaces intermedios comunes: la programación empresarial está orientada a modelos e interfaces intermedios y se presta mejor atención a los atributos empresariales correspondientes al protocolo.

NOTA: ¡Haga clic en la imagen para verla claramente!

4.2 Módulo de enrutamiento

El módulo de enrutamiento es uno de los dos componentes principales del plano de control. Además de gestionar la relación de mapeo entre puertas de enlace y servicios, el servicio en sí se puede resumir en el siguiente modelo:

{
    
    
    //匹配方式
    "type": "uri",

    //HTTP默认采用uri前缀匹配,内部通过树结构寻址;私有协议(SOTP)通过服务唯一标识定位。
    "value": "/hotel/order",
    "matcherType": "prefix",

    //标签与属性
    //用于portal端权限管理、切面逻辑运行(如按核心/非核心)等
    "tags": [
        "owner_admin",
        "org_framework",
        "appId_123456"
    ],
    "properties": {
    
    
        "core": "true"
    },

    //endpoint信息
    "routes": [{
    
    
        //condition用于二级路由,如按app版本划分、按query重分配等
        "condition": "true",
        "conditionParam": {
    
    },
        "zone": "PRO",

        //具体服务地址,权重用于灰度场景
        "targets": [{
    
    
            "url": "http://test.ctrip.com/hotel",
            "weight": 100
        }
                   ]
    }]
}

4.3 Disposición del módulo

La programación del módulo es otro componente clave del plano de control. Tenemos varias etapas en el flujo de procesamiento de la puerta de enlace (que se muestran en rosa en el diagrama). Además de funciones comunes como disyuntores, limitación de corriente y registro, durante el tiempo de ejecución, el plano de control asigna uniformemente las funciones comerciales que deben realizar las diferentes puertas de enlace. Estas funciones tienen módulos de código independientes dentro de la puerta de enlace, y el plano de control define adicionalmente las condiciones de ejecución, los parámetros, la escala de grises y los métodos de manejo de errores correspondientes a estas funciones. Este método de programación también garantiza hasta cierto punto el desacoplamiento entre módulos.

NOTA: ¡Haga clic en la imagen para verla claramente!

{
    
    
    //模块名称,对应网关内部某个具体模块
    "name": "addResponseHeader",

    //执行阶段
    "stage": "PRE_RESPONSE",

    //执行顺序
    "ruleOrder": 0,

    //灰度比例
    "grayRatio": 100,

    //执行条件
    "condition": "true",
    "conditionParam": {
    
    },

    //执行参数
    //大量${}形式的内置模板,用于获取运行时数据
    "actionParam": {
    
    
        "connection": "keep-alive",
        "x-service-call": "${request.func.remoteCost}",
        "Access-Control-Expose-Headers": "x-service-call",
        "x-gate-root-id": "${func.catRootMessageId}"
    },

    //异常处理方式,可以抛出或忽略
    "exceptionHandle": "return"
}

5. Resumen

Gateway siempre ha sido un tema de gran preocupación en varias plataformas de intercambio técnico, y hay muchas soluciones maduras: Zuul 1.0, que es fácil de usar y desarrollado anteriormente, Nginx de alto rendimiento, Spring Cloud Gateway con alta integración y el cada vez más popular. Istio, etc.

La selección final aún depende de la experiencia empresarial y el ecosistema tecnológico de cada empresa.

Por eso, en Ctrip, hemos elegido el camino de la investigación y el desarrollo independientes.

La tecnología está en constante desarrollo y nosotros también seguimos explorando, incluida la relación entre gateways públicos y gateways empresariales, la aplicación de nuevos protocolos (como HTTP3), la asociación con ServiceMesh, etc.

Al final: Si tienes alguna duda, puedes pedir consejo a la arquitectura antigua.

El camino hacia la arquitectura está lleno de altibajos

La arquitectura es diferente del desarrollo avanzado: las preguntas de arquitectura son abiertas / abiertas y no hay respuestas estándar para las preguntas de arquitectura.

Debido a esto, muchos amigos, a pesar de gastar mucha energía y dinero, desafortunadamente nunca completan la actualización de la arquitectura en su vida .

Por lo tanto, en el proceso de actualización/transformación de la arquitectura, si realmente no puede encontrar una solución eficaz, puede acudir al arquitecto Nien, de 40 años, en busca de ayuda.

Hace algún tiempo, tenía un amigo que trabajó en Java en varias especialidades y ahora se enfrenta al problema de cambiar de arquitectura. Sin embargo, después de varias rondas de orientación de Nien, consiguió con éxito la oferta de arquitecto Java + arquitecto de big data . Por lo tanto, si encuentra dificultades profesionales, será mucho más sencillo pedir ayuda a un arquitecto experimentado.

Lectura recomendada

" Decenas de miles de millones de visitas, cómo diseñar la arquitectura de caché "

" Diseño de arquitectura de caché multinivel "

" Diseño de arquitectura de inserción de mensajes "

" Alibaba 2: ¿Cuántos nodos implementas?" ¿Cómo implementar concurrencia de 1000W?

" Meituan 2 lados: 99,999% 99,999% de 5 nueves, ¿cómo lograrlo?"

" Lado de NetEase: nodo único 2000Wtps, ¿cómo lo hace Kafka?"

" Lado del byte: compensación de transacción y reintento de transacción, ¿cuál es la relación?"

" Lado de NetEase: escritura Mysql de alto rendimiento de 25 Wqps, datos de 100 W se escriben en 4 segundos, ¿cómo lograrlo?"

" ¿ Cómo estructurar vídeos cortos de mil millones de niveles? "

" Burst, confiando en "fanfarronear" para vivir en JD.com, con un salario mensual de 40.000 "

" Es tan feroz que confío en" fanfarronear "para pasar por SF Express, y mi salario mensual es de 30.000 " .

" Explotó... Jingdong pidió 40 preguntas en un lado y, después de aprobarlas, fueron más de 500.000 " .

" Estoy tan cansado de hacer preguntas... Ali hizo 27 preguntas mientras preguntaba por su vida, y después de aprobarlas, son 600.000+ "

" Después de 3 horas de preguntas locas sobre Baidu, recibí una oferta de una gran empresa. ¡Este tipo es tan cruel!"

" Ele.me es demasiado cruel: frente a un Java avanzado, qué duro y cruel es el trabajo "

" Después de una hora de preguntas locas por parte de Byte, el tipo recibió la oferta, ¡es tan cruel!"

" Acepta una oferta de Didi: De las tres experiencias del chico, ¿qué necesitas aprender?

"Notas de arquitectura de Nien", "Trilogía de alta concurrencia de Nien", "Guía de entrevistas de Nien Java" PDF, vaya a la siguiente cuenta oficial [Technical Freedom Circle] para obtener ↓↓↓

Supongo que te gusta

Origin blog.csdn.net/crazymakercircle/article/details/132672467
Recomendado
Clasificación