api-gateway模式

374 阅读3分钟

标签

API网关

意图

在单个位置(API网关)聚合对微服务的调用。用户只进行一次调用, 然后API网关调用每个相关的微服务。

解释

使用微服务模式,客户机可能需要来自多个不同微服务的数据。如果客户机直接调用每个微服务,这可能会延长加载时间,因为客户端必须为每个被调用的微服务发出网络请求。而且,客户端调用每个微服务直接将客户端绑定到该微服务-如果内部微服务的实现会发生变化(例如,如果两个微服务在某个时候组合在一起).如果微服务的位置(主机和端口)发生变化,则必须更新这些微服务的使用。

API网关模式的目的是缓解其中一些问题。在API网关中模式中,在客户端和微服务之间放置一个附加实体(API网关)。 API网关的工作是聚合对微服务的调用。而不是客户机单独调用每个微服务,只调用一次API网关。API 网关然后调用客户端需要的每个微服务。

现实世界中的例子

我们正在为一个电子商务站点实现微服务和API网关模式。在这个系统中, API网关调用图像和价格微服务。

简单地说

对于使用微服务体系结构实现的系统,API网关是单一入口点 聚合对单个微服务的调用。

维基百科说

API网关是充当API前端、接收API请求、强制限制的服务器和安全策略,将请求传递给后端服务,然后将响应传递回后端服务给请求者。网关通常包括一个转换引擎,用于编排和修改、即时的请求和响应。网关还可以提供收集数据等功能, 分析数据并提供缓存。网关可以提供支持的功能, 认证、授权、安全、审计和法规遵从性。

适用性

在以下情况下使用API网关模式:您使用的是微服务体系结构,需要为微服务调用提供一个聚合点。


以上是github项目的解释

个人对网关的理解

网关作用就是动态代理, 是暴露给外部的调用服务, 所有请求的入口, 用户无法直接调用内部的服务接口, 必须先经过网关, 再由网关转发至具体的服务

中间网的网络关系

  • 网关服务和外部网络联通
  • 内部服务不会暴露给外部
  • 网关服务和内部服务网络都在内网, 是连通的

网关还会做一些通用的操作, 如限流、权限校验、通用日志等操作...

具体流程, 如下图所示: image.png

通过代码学习了服务间的调用的代码该如何写, 以及对maven操作的一些理解(这个再另开一篇文章说明)

@Slf4j
@Component
public class PriceClientImpl implements PriceClient {
  @Autowired
  private RestTemplate restTemplate;

  @Override
  public String getPrice() {
    // 设置请求头
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    // 构造请求的对象
    HttpEntity httpEntity = new HttpEntity(headers);
    try {
      // 通过spring提供的restTemplate进行调用
      ResponseEntity<String> responseEntity = restTemplate.exchange("http://localhost:50006/price", HttpMethod.GET, httpEntity, String.class);
      logResponse(responseEntity);
      return responseEntity.getBody();
    } catch (RestClientException e) {
      // 调用异常日志打印
      log.error("Failure occurred while getting price info", e);
    }
    return null;
  }

  /**
   * 打印返回的信息处理
   * @param responseEntity
   */
  private void logResponse(ResponseEntity responseEntity) {
    if (isSuccessResponse(responseEntity.getStatusCode().value())) {
      log.info("Price info received successfully");
    } else {
      log.warn("Price info request failed");
    }
  }

  /**
   * 根据响应的码值来判断请求是否处理成功
   * 认为 200-299都是处理成功
   * @param responseCode
   * @return
   */
  private boolean isSuccessResponse(int responseCode) {
    return responseCode >= 200 && responseCode <= 299;
  }
}

项目github地址