• 3、网关和BFF


    一、网关和BFF的演进

    1. v1 使用nginx负载均衡简单的微服务体系;

    2. v2 nginx直接暴露

    3. v2.5无线BFF

    4. v3 集群BFF+无线网关

    5. v4无线网关、无线BFF根据业务集群化,废弃nginx集群

      二、网关和反向代理

    网关和反向代理的选择:

     

    关于网关集群问题:需要根据公司业务大小进行选择 

     三、设计简单网关-faraday

    1.核心思想

    2.代码实现

    • 路由映射表模块 
      • MappingsProvider路由映射表
        1. package xyz.staffjoy.faraday.core.mappings;
        2. import com.github.structlog4j.ILogger;
        3. import com.github.structlog4j.SLoggerFactory;
        4. import org.springframework.boot.autoconfigure.web.ServerProperties;
        5. import xyz.staffjoy.faraday.config.FaradayProperties;
        6. import xyz.staffjoy.faraday.config.MappingProperties;
        7. import xyz.staffjoy.faraday.core.http.HttpClientProvider;
        8. import javax.annotation.PostConstruct;
        9. import javax.servlet.http.HttpServletRequest;
        10. import java.util.List;
        11. import java.util.stream.Collectors;
        12. import static org.springframework.util.CollectionUtils.isEmpty;
        13. public abstract class MappingsProvider {
        14. private static final ILogger log = SLoggerFactory.getLogger(MappingsProvider.class);
        15. protected final ServerProperties serverProperties;
        16. protected final FaradayProperties faradayProperties;
        17. protected final MappingsValidator mappingsValidator;
        18. protected final HttpClientProvider httpClientProvider;
        19. protected List mappings;
        20. public MappingsProvider(
        21. ServerProperties serverProperties,
        22. FaradayProperties faradayProperties,
        23. MappingsValidator mappingsValidator,
        24. HttpClientProvider httpClientProvider
        25. ) {
        26. this.serverProperties = serverProperties;
        27. this.faradayProperties = faradayProperties;
        28. this.mappingsValidator = mappingsValidator;
        29. this.httpClientProvider = httpClientProvider;
        30. }
        31. public MappingProperties resolveMapping(String originHost, HttpServletRequest request) {
        32. if (shouldUpdateMappings(request)) {
        33. updateMappings();
        34. }
        35. List resolvedMappings = mappings.stream()
        36. .filter(mapping -> originHost.toLowerCase().equals(mapping.getHost().toLowerCase()))
        37. .collect(Collectors.toList());
        38. if (isEmpty(resolvedMappings)) {
        39. return null;
        40. }
        41. return resolvedMappings.get(0);
        42. }
        43. @PostConstruct
        44. protected synchronized void updateMappings() {
        45. List newMappings = retrieveMappings();
        46. mappingsValidator.validate(newMappings);
        47. mappings = newMappings;
        48. httpClientProvider.updateHttpClients(mappings);
        49. log.info("Destination mappings updated", mappings);
        50. }
        51. protected abstract boolean shouldUpdateMappings(HttpServletRequest request);
        52. protected abstract List retrieveMappings();
        53. }
        resolveMapping:根据主机头获取路由映射;
        updateMappings:更新路由表;
    • http映射表
      • 根据路由映射表获取到的路由,通过http映射表对目标服务发起调用
        1. package xyz.staffjoy.faraday.core.http;
        2. import org.apache.http.impl.client.CloseableHttpClient;
        3. import org.apache.http.impl.client.HttpClientBuilder;
        4. import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
        5. import org.springframework.web.client.RestTemplate;
        6. import xyz.staffjoy.faraday.config.MappingProperties;
        7. import java.util.HashMap;
        8. import java.util.List;
        9. import java.util.Map;
        10. import static java.util.stream.Collectors.toMap;
        11. import static org.apache.http.impl.client.HttpClientBuilder.create;
        12. public class HttpClientProvider {
        13. protected Map httpClients = new HashMap<>();
        14. public void updateHttpClients(List mappings) {
        15. httpClients = mappings.stream().collect(toMap(MappingProperties::getName, this::createRestTemplate));
        16. }
        17. public RestTemplate getHttpClient(String mappingName) {
        18. return httpClients.get(mappingName);
        19. }
        20. protected RestTemplate createRestTemplate(MappingProperties mapping) {
        21. CloseableHttpClient client = createHttpClient(mapping).build();
        22. HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(client);
        23. requestFactory.setConnectTimeout(mapping.getTimeout().getConnect());
        24. requestFactory.setReadTimeout(mapping.getTimeout().getRead());
        25. return new RestTemplate(requestFactory);
        26. }
        27. protected HttpClientBuilder createHttpClient(MappingProperties mapping) {
        28. return create().useSystemProperties().disableRedirectHandling().disableCookieManagement();
        29. }
        30. }

    四、大型网关扩展

    • 限流熔断:保障用户体验,保障服务不会挂断
    • 动态路由和负载均衡:当服务多时,采用动态服务发现机制,k8s内部支持
    • 基于Path的路由:通过域名映射到服务
    • 截获器链:多个截获器构成的链状
    • 日志采集和Metrics埋点:日志+日志分析;掌握后台性能状况
    • 响应流优化:响应速度大时,内核态无需拷贝到用户态,直接以流的形式提供给网关

    五、主流网关概览

     

  • 相关阅读:
    kubernetes的这几种存储卷,别再傻傻分不清了
    Vue2动态显示时间
    [React Hooks]性能调优与自定义钩子
    Java:代理模式详解
    通信工程学习:什么是接入网(AN)中的CF核心功能
    ubuntu 20.04 Kimera semantic 运行记录
    【云原生-Kurbernetes篇】K8s的存储卷/数据卷+PV与PVC
    【SpringMVC】springmvc中的数据校验
    【Jackson】自定义注解结合Jackson
    【稳定性】稳定性建设之弹性设计
  • 原文地址:https://blog.csdn.net/kk_lina/article/details/128057324