美文网首页
服务发现:客户端服务发现

服务发现:客户端服务发现

作者: scheshan | 来源:发表于2018-08-29 07:44 被阅读0次

    背景

    服务通常需要调用其他服务。单体应用中,服务通过语言级别的方法或者过程调用另外的服务。在传统的分布式部署中,服务运行在固定,已知的地址(主机和端口),因此可以请求的通过HTTP/REST或其他RPC机制调用。然而,一个现代的微服务应用通常运行在虚拟或者容器环境,服务实例数和它们的地址都在动态改变。

    服务发现

    因此,你需要实现一种机制,允许服务的客户端向动态变更的一组短暂的服务实例发起请求。

    问题

    如何让服务的客户端 - API网关或者其他服务 - 发现服务实例的地址

    限制

    • 每个服务在特定地址(主机和端口)实例暴露一个远程API,比如HTTP/REST,或者Thrift等等
    • 服务实例的数量和他们的地址动态改变。
    • 虚拟机和容器通常分配动态IP。
    • 服务实例数可能动态变化。比如,EC2 Autoscaling Group基于负载确定实例数。

    解决方案

    当发起对服务的请求时,客户端通过查询一个服务注册中心或者服务实例的地址,服务注册中心知道所有服务实例的地址。

    下图介绍了这个模式的架构。

    image

    这很典型的已经被微服务基架处理。

    示例

    微服务示例应用是使用了客户端服务发现的一个例子。它用Scala编写,使用了Spring Boot和Spring Cloud作为微服务基架。它们提供了许多功能,包括客户端服务发现。

    RegistrationServiceProxy 是该应用的一个组件。为了注册用户,它通过Spring框架的RestTemplate调用其他服务:

    @Component
    class RegistrationServiceProxy @Autowired()(restTemplate: RestTemplate) extends RegistrationService {
    
      @Value("${user_registration_url}")
      var userRegistrationUrl: String = _
    
      override def registerUser(emailAddress: String, password: String): Either[RegistrationError, String] = {
    
          val response = restTemplate.postForEntity(userRegistrationUrl,
            RegistrationBackendRequest(emailAddress, password),
            classOf[RegistrationBackendResponse])
           ...
    }
    
    

    它和RestTemplate一起被注入,同时还有user_registration_url,它指定了REST的端点。

    当应用部署时,user_registration_url被设置为URL http://REGISTRATION-SERVICE/user - 参见 docker-compose.yml 文件。REGISTRATION-SERVICE 是个逻辑的服务名字,通过客户端服务发现被解析成一个网络地址。服务发现使用了 Netflix OSS 组件。它提供了 Eureka:一个服务注册中心,以及 Ribbon:一个HTTP客户端,查询Eureka以路由HTTP请求到可用的服务实例。

    客户端服务发现通过一些Spring Cloud注解来配置

    @Configuration
    @EnableEurekaClient
    @Profile(Array("enableEureka"))
    class EurekaClientConfiguration {
    
      @Bean
      @LoadBalanced
      def restTemplate(scalaObjectMapper : ScalaObjectMapper) : RestTemplate = {
        val restTemplate = new RestTemplate()
        restTemplate.getMessageConverters foreach {
          case mc: MappingJackson2HttpMessageConverter =>
            mc.setObjectMapper(scalaObjectMapper)
          case _ =>
        }
        restTemplate
      }
    
    

    @EnableEurekaClient注解启用了Eureka客户端。@LoadBalanced注解配置了RestTemplate使用Ribbon,Ribbon被设置为使用Eureka客户端来实现服务发现。因此,RestTemplate将通过查询Eureka,找出可用服务实例的网络地址,来处理对 http://REGISTRATION-SERVICE/user 的请求

    结果

    客户端服务发现有如下优势:

    客户端服务发现有如下弊端:

    • 这个模式将客户端和服务注册中心耦合
    • 你必须为应用使用的每个编程语言 / 框架实现客户端服务发现的逻辑,比如Java / Scala,JavaScript / NodeJS。比如,Netflix Prana 为非JVM的客户端提供了一个以HTTP代理为基础的方式。

    相关模式

    相关文章

      网友评论

          本文标题:服务发现:客户端服务发现

          本文链接:https://www.haomeiwen.com/subject/qfhcwftx.html