前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解服务发现:从基础到实践

深入理解服务发现:从基础到实践

作者头像
栗筝i
发布2023-10-16 14:45:41
1.4K0
发布2023-10-16 14:45:41
举报
文章被收录于专栏:迁移内容

随着微服务架构的广泛应用,服务发现已经成为了一个不可或缺的组成部分。服务发现是微服务架构中的一个关键问题,它涉及到如何管理和协调在一个分布式系统中的大量服务。本文将深入探讨服务发现的基本概念、工作原理和实践应用。我们将首先介绍服务发现的基本概念和工作原理,然后通过实际案例来展示服务发现在实践中的应用,最后我们将探讨服务发现的挑战和未来发展趋势。希望通过本文,读者能够对服务发现有一个全面和深入的理解

1、服务发现简介
1.1、微服务架构的基本概念

微服务架构是一种将单一应用程序划分为一组小的服务的架构风格。每个服务都运行在其自身的进程中,服务之间通过轻量级的机制(通常是HTTP资源API)进行通信。这些服务都围绕业务能力构建,并且可以通过全自动部署机制独立地进行部署。此外,这些服务可以用不同的编程语言编写,并使用不同的数据存储技术。

img
img
1.2、服务发现的基本概念

服务发现是分布式系统中的一个关键组件,它的主要功能是跟踪系统中所有服务的网络位置。在微服务架构中,由于服务数量众多且位置可能频繁变动,因此需要服务发现机制来动态地查找和监控服务。

服务发现通常包括服务注册和服务查找两个主要过程。服务注册是指服务启动时将自己的网络地址注册到服务注册中心;服务查找是指当一个服务需要调用另一个服务时,通过查询服务注册中心来获取被调用服务的网络地址。

通过服务发现,各个服务无需关心其他服务的具体位置,只需要知道服务的名称即可进行通信,大大提高了系统的灵活性和可扩展性。

1.3、服务发现在微服务架构中的重要性

在微服务架构中,服务发现的重要性主要体现在以下几个方面:

  1. 系统解耦:通过服务发现,各个服务无需关心其他服务的具体位置,只需要知道服务的名称即可进行通信,这大大降低了服务之间的耦合度。
  2. 提高可扩展性:由于服务的位置信息由服务发现系统管理,因此当需要增加或减少服务实例时,只需要在服务发现系统中进行更新即可,无需修改调用服务的代码。
  3. 提高可用性:服务发现系统通常会对服务进行健康检查,当某个服务出现故障时,可以快速将其从服务列表中移除,防止调用方调用到故障的服务。
  4. 负载均衡:服务发现系统可以配合负载均衡器使用,根据服务的负载情况动态地调整服务的调用。

因此,服务发现在微服务架构中起着至关重要的作用。

2、服务发现的工作原理

服务发现的工作原理主要包括两个步骤:服务注册和服务查找

2.1、服务注册

服务注册:当一个服务(例如,一个微服务实例)启动时,它会将自己的网络地址(如IP地址和端口号)以及其他可能的信息(如服务名称、版本号等)发送到服务注册中心。服务注册中心负责存储和维护这些信息,以便其他服务在需要与该服务通信时,可以通过查询服务注册中心来获取该服务的网络地址。这种机制使得服务之间可以动态地发现和通信,提高了系统的灵活性和可扩展性。

image-20230927154742592
image-20230927154742592
2.2、服务查找

服务查找:服务查找是服务发现过程中的另一个重要步骤。当一个服务(例如,一个微服务实例)需要调用另一个服务时,它会向服务注册中心请求被调用服务的网络地址。服务注册中心会返回被调用服务的地址,然后调用方就可以直接与被调用服务进行通信。这种机制使得服务之间可以动态地发现和通信,提高了系统的灵活性和可扩展性。

2.3、负载均衡

服务注册中心也需要具备负载均衡的能力。在大型的分布式系统中,服务注册中心可能需要处理大量的服务注册和查找请求,如果所有的请求都由一个服务注册中心处理,可能会成为系统的瓶颈。因此,通常会部署多个服务注册中心实例,并通过负载均衡机制将请求分发到不同的实例上,以提高系统的处理能力和可用性。

此外,服务注册中心还需要提供一种机制,使得当一个服务有多个实例时,可以根据一定的策略(如轮询、随机、根据负载情况等)选择一个实例返回给调用方,这也是一种负载均衡的方式。

因此,服务注册中心不仅需要管理服务的注册和查找,还需要具备负载均衡的能力,以确保系统的高可用性和高性能。

2.4、服务监测

服务监测:服务注册中心需要对注册的服务进行监测,包括服务的可用性、响应时间、错误率等指标。这些监测数据可以用于分析服务的运行状况,及时发现和解决问题。

其中,服务的可用性检测通常通过健康检查(Health Check)来实现:

2.5、健康检查

健康检查:服务注册中心通常会定期对注册的服务进行健康检查,检查服务是否仍然可用。健康检查通常是通过向服务发送一个简单的请求,如 HTTP 的 HEAD 请求,如果服务正常响应,则认为服务是健康的;如果服务无法响应,或者响应错误,那么服务注册中心会认为服务不健康,将其从服务列表中移除,防止其他服务调用到不可用的服务。

2.6、动态更新

服务发现注册中心的动态更新是指,当服务的状态发生变化(如服务上线、下线、故障等)时,服务注册中心能够实时地更新服务的状态信息。

具体来说,动态更新主要包括以下几个方面:

  1. 服务注册:当新的服务实例启动时,它会将自己的网络地址和其他必要信息注册到服务注册中心,服务注册中心会将这些信息添加到服务列表中。
  2. 服务注销:当服务实例停止时,它会将自己从服务注册中心注销,服务注册中心会将该服务从服务列表中移除。
  3. 服务更新:如果服务的网络地址或其他信息发生变化,服务可以更新在服务注册中心的注册信息。
  4. 健康检查:服务注册中心会定期对服务进行健康检查,如果发现服务无法正常响应,会将该服务标记为不可用,或者从服务列表中移除。

通过这种动态更新机制,服务注册中心能够实时地反映系统中服务的最新状态,从而使得服务之间能够动态地发现和通信,提高系统的灵活性和可用性。

2.7、各种协议的优缺点

服务发现可以使用各种协议,包括 HTTP、RPC、DNS 等,各种协议都有其优缺点:

HTTP:

  • 优点:HTTP 是一种通用的、基于文本的协议,易于理解和调试,可以通过各种工具和库进行处理,适用于各种语言和平台;
  • 缺点:HTTP 的性能可能不如二进制协议,特别是在大规模的服务发现场景下。此外,HTTP 是一种无状态的协议,不适合需要长连接的场景

RPC(如 gRPC、Thrift):

  • 优点:RPC 通常比 HTTP 更轻量级,性能更高。许多 RPC 框架都提供了服务发现的功能,可以与 RPC 通信紧密集成,使用起来更方便;
  • 缺点:RPC 需要特定的客户端库,不如 HTTP 通用。此外,一些 RPC 协议可能不易通过网络防火墙

DNS:

  • 优点:DNS 是一种基于域名的服务发现协议,可以直接使用操作系统的 DNS 解析功能,无需额外的客户端库。此外,DNS 可以很好地支持负载均衡和故障转移;
  • 缺点:DNS 的更新延迟较高,不适合频繁变动的环境。此外,DNS 不支持服务的元数据,如服务的版本、状态等。

以上是服务发现使用各种协议的一些优缺点,具体选择哪种协议取决于系统的具体需求和环境。

3、服务发现的实现
3.1、服务发现提供者实现

服务发现的服务提供者实现主要包括以下几个步骤:

  1. 启动时注册:当服务启动时,它会将自己的信息(如服务名称、地址、端口等)注册到服务注册中心。这通常是通过调用服务注册中心的 API 来实现的。
  2. 定期发送心跳:为了让服务注册中心知道服务仍然可用,服务需要定期向服务注册中心发送心跳。如果服务注册中心在一段时间内没有收到服务的心跳,它会认为该服务已经下线。
  3. 健康检查:服务可能会提供一个健康检查的接口,让服务注册中心可以检查服务的健康状态。如果服务的健康状态发生变化,服务需要更新在服务注册中心的注册信息。
  4. 关闭时注销:当服务关闭时,它需要将自己从服务注册中心注销,以防止其他服务尝试调用已经不可用的服务。

以下是一个使用 Spring Cloud 和 Eureka 实现的服务提供者的例子:

代码语言:javascript
复制
@SpringBootApplication
@EnableEurekaClient
public class ServiceProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceProviderApplication.class, args);
    }
}

在这个例子中,@EnableEurekaClient 注解启用了 Eureka 客户端,这使得服务在启动时自动注册到 Eureka 服务器,并定期发送心跳。服务的其他信息(如服务名称、地址、端口等)可以在配置文件中设置。

3.2、服务发现消费者实现

服务发现的服务消费者实现主要包括以下几个步骤:

  1. 查询服务:当服务消费者需要调用其他服务时,它首先需要查询服务注册中心,获取服务提供者的信息。这通常是通过调用服务注册中心的 API 来实现的。
  2. 负载均衡:如果有多个服务提供者提供相同的服务,服务消费者需要选择其中一个进行调用。这通常是通过负载均衡算法(如轮询、随机、最少连接等)来实现的。
  3. 错误处理:如果服务调用失败(如网络错误、服务不可用等),服务消费者需要进行错误处理。这可能包括重试、回退、熔断等策略。

以下是一个使用 Spring Cloud 和 Eureka 实现的服务消费者的例子:

代码语言:javascript
复制
@SpringBootApplication
@EnableDiscoveryClient
public class ServiceConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceConsumerApplication.class, args);
    }

    @Autowired
    private DiscoveryClient discoveryClient;

    public void doSomething() {
        List<ServiceInstance> instances = discoveryClient.getInstances("service-provider");
        if (!instances.isEmpty()) {
            ServiceInstance instance = instances.get(0); // 这里简单地取第一个实例,实际应用中可能需要使用负载均衡算法
            // 使用 instance.getHost() 和 instance.getPort() 获取服务地址和端口,然后进行服务调用
        }
    }
}

在这个例子中,@EnableDiscoveryClient 注解启用了服务发现客户端,这使得服务可以查询 Eureka 服务器获取服务提供者的信息。doSomething 方法中,我们首先通过 discoveryClient.getInstances 方法获取服务提供者的信息,然后进行服务调用。

服务发现的服务消费者实现主要包括以下几个步骤:

  1. 查询服务:当服务消费者需要调用其他服务时,它首先需要查询服务注册中心,获取服务提供者的信息。这通常是通过调用服务注册中心的 API 来实现的。
  2. 负载均衡:如果有多个服务提供者提供相同的服务,服务消费者需要选择其中一个进行调用。这通常是通过负载均衡算法(如轮询、随机、最少连接等)来实现的。
  3. 错误处理:如果服务调用失败(如网络错误、服务不可用等),服务消费者需要进行错误处理。这可能包括重试、回退、熔断等策略。

以下是一个使用 Spring Cloud 和 Eureka 实现的服务消费者的例子:

代码语言:javascript
复制
@SpringBootApplication
@EnableDiscoveryClient
public class ServiceConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceConsumerApplication.class, args);
    }

    @Autowired
    private DiscoveryClient discoveryClient;

    public void doSomething() {
        List<ServiceInstance> instances = discoveryClient.getInstances("service-provider");
        if (!instances.isEmpty()) {
            ServiceInstance instance = instances.get(0); // 这里简单地取第一个实例,实际应用中可能需要使用负载均衡算法
            // 使用 instance.getHost() 和 instance.getPort() 获取服务地址和端口,然后进行服务调用
        }
    }
}

在这个例子中,@EnableDiscoveryClient 注解启用了服务发现客户端,这使得服务可以查询 Eureka 服务器获取服务提供者的信息。doSomething 方法中,我们首先通过 discoveryClient.getInstances 方法获取服务提供者的信息,然后进行服务调用。

3.3、服务发现注册中心实现

服务发现的注册中心实现主要包括以下几个步骤:

  1. 接收服务注册:注册中心需要提供一个接口,让服务提供者可以将自己的信息(如服务名称、地址、端口等)注册到注册中心。
  2. 存储服务信息:注册中心需要将服务提供者的信息存储起来,以便服务消费者查询。这通常需要使用某种数据库或内存数据结构来实现。
  3. 提供服务查询:注册中心需要提供一个接口,让服务消费者可以查询服务提供者的信息。
  4. 接收服务心跳:注册中心需要接收服务提供者的心跳,以了解服务提供者的存活状态。如果在一段时间内没有收到服务提供者的心跳,注册中心会认为该服务已经下线。
  5. 提供服务注销:注册中心需要提供一个接口,让服务提供者在关闭时可以将自己从注册中心注销。

以下是一个使用 Spring Boot 和 HTTP 实现的简化的服务注册中心的例子:

代码语言:javascript
复制
@SpringBootApplication
@RestController
public class RegistryCenterApplication {
    private Map<String, String> services = new ConcurrentHashMap<>();

    public static void main(String[] args) {
        SpringApplication.run(RegistryCenterApplication.class, args);
    }

    @PostMapping("/register")
    public void register(@RequestParam String serviceName, @RequestParam String serviceAddress) {
        services.put(serviceName, serviceAddress);
    }

    @GetMapping("/discover")
    public String discover(@RequestParam String serviceName) {
        return services.get(serviceName);
    }
}

在这个例子中,我们使用一个 ConcurrentHashMap 来存储服务信息,/register 接口用于服务注册,/discover 接口用于服务查询。这只是一个非常简化的例子,实际的服务注册中心会更复杂,需要处理并发、网络通信、错误处理、服务健康检查等问题。

3.4、Java实现注册中心简单案例

实现一个完整的服务注册中心涉及到的内容较多,包括网络编程、多线程编程、错误处理等,以下是一个简化的例子,使用 Spring Boot 和 HTTP 实现服务注册、服务查找和健康检查的功能。

首先,我们定义一个 ServiceInstance 类来表示服务实例:

代码语言:javascript
复制
public class ServiceInstance {
    private String serviceName;
    private String host;
    private int port;

    // 构造函数、getter 和 setter 省略
}

然后,我们定义一个 ServiceRegistry 类来实现服务注册和发现的功能:

代码语言:javascript
复制
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class ServiceRegistry {
    private Map<String, ServiceInstance> services = new ConcurrentHashMap<>();

    public void register(ServiceInstance instance) {
        services.put(instance.getServiceName(), instance);
    }

    public ServiceInstance discover(String serviceName) {
        return services.get(serviceName);
    }
}

接下来,我们定义一个 RegistryController 类来处理 HTTP 请求:

代码语言:javascript
复制
import org.springframework.web.bind.annotation.*;

@RestController
public class RegistryController {
    private final ServiceRegistry registry;

    public RegistryController(ServiceRegistry registry) {
        this.registry = registry;
    }

    @PostMapping("/register")
    public void register(@RequestBody ServiceInstance instance) {
        registry.register(instance);
    }

    @GetMapping("/discover/{serviceName}")
    public ServiceInstance discover(@PathVariable String serviceName) {
        return registry.discover(serviceName);
    }
}

最后,我们可以定义一个定时任务来进行服务健康检查:

代码语言:javascript
复制
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class HealthCheckTask {
    private final ServiceRegistry registry;

    public HealthCheckTask(ServiceRegistry registry) {
        this.registry = registry;
    }

    @Scheduled(fixedRate = 60000)
    public void healthCheck() {
        // 对 registry 中的每个服务进行健康检查,如果检查失败,移除该服务
    }
}

这只是一个简化的例子,实际的服务注册中心会更复杂。例如,处理并发可能需要使用锁或其他并发控制机制;网络通信可能需要使用更复杂的协议,如 TCP、UDP 或 HTTP/2;错误处理可能需要考虑各种网络错误、超时、服务故障等情况。


4、服务发现的实际应用案例
4.1、服务发现开源软件-Eureka

Eureka 是 Netflix 开源的一款提供服务注册和发现的产品,它是 Spring Cloud 生态系统中的一部分,主要用于实现微服务架构中的服务治理功能。Eureka 的主要特点包括:

  1. 简单易用:Eureka 提供了简单易用的注解和配置属性,开发者可以很方便地将 Eureka 集成到 Spring Cloud 项目中;
  2. 服务注册与发现:Eureka Server 提供了服务注册功能,各个微服务节点启动后,会在 Eureka Server 中进行注册。Eureka Client 可以从 Eureka Server 中获取注册信息,实现服务发现;
  3. 客户端负载均衡:Eureka Client 内置了负载均衡器,可以很好地控制请求到各个服务节点的分发;
  4. 高可用:Eureka Server 可以配置为高可用模式,通过互相注册的方式,形成一个服务注册中心集群;
  5. 自我保护:在网络分区故障发生(延迟、卡顿、服务未正常下线等)时,Eureka Server 会保护服务注册表中的信息,不会立即将服务注册信息删除,使得微服务仍可用。
4.2、服务发现开源软件-Etcd

Etcd 是由 CoreOS 开发基于 Go 语言实现的,是一个开源的、高可用的分布式键值存储系统,用于共享配置和服务发现。Etcd 的主要特点包括:

  1. 简单易用:Etcd 的安装和配置都非常简单,提供了 HTTP API 进行交互,使用起来也很方便;
  2. 键值对存储:Etcd 是一个键值对存储系统,数据存储在分层组织的目录中,就像在标准文件系统中一样;
  3. 变更监测:Etcd 可以监测特定的键或目录的变化,并对值的更改做出反应,这对于实现动态配置更新和服务发现非常有用;
  4. 高性能:根据官方提供的 benchmark 数据,Etcd 的单实例支持每秒 2k+ 的读操作,可以满足大多数应用的需求;
  5. 高可用和一致性:Etcd 使用 Raft 算法,实现了分布式系统数据的可用性和一致性。即使部分节点发生故障,Etcd 仍能保证数据的可用性和一致性
4.3、服务发现开源软件-ZooKeeper

ZooKeeper 是 Apache 的一个开源项目,它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。ZooKeeper 的主要特点包括:

  1. 简单易用:ZooKeeper 的模型是一个树形的目录结构,非常类似于文件系统。它提供了一组简单的 API,如创建节点、删除节点、读取节点数据、设置节点数据等,使用起来非常方便;
  2. 变更通知:ZooKeeper 支持 Watcher 机制,客户端可以在一个节点上注册一个 Watcher,当节点的数据发生变化时,Watcher 会得到通知。这对于实现配置动态更新、服务发现等功能非常有用;
  3. 高性能:ZooKeeper 采用了一种叫做 ZAB 的协议来保证高可用和一致性,它可以处理大量的读和稳定的写操作;
  4. 高可用和一致性:ZooKeeper 通过复制机制,将数据复制到各个工作节点上,只要半数以上的节点存活,ZooKeeper 就能正常服务。同时,ZooKeeper 保证了客户端能读到的数据都是最新的。
  5. 顺序一致性:ZooKeeper 保证了从同一个客户端发起的事务请求,最终将会按照发起的顺序在 ZooKeeper 中被应用。
4.4、服务发现开源软件-Nacos

Nacos 是阿里巴巴开源的一款易于使用的平台,用于管理、发现和配置微服务。Nacos 提供了一组简单的 API 来实现服务的注册、发现和健康检查。Nacos 的主要特点包括:

  1. 简单易用:Nacos 提供了一套简单易用的 API 和界面,使得开发者可以方便地管理和操作服务。
  2. 服务注册与发现:Nacos 提供了服务注册中心,支持服务的动态注册和发现,支持 DNS 和 HTTP 两种服务发现方式。
  3. 动态配置服务:Nacos 提供了动态配置服务,支持配置的版本管理、配置更新推送等功能,使得应用可以在运行时动态地获取和更新配置。
  4. 高可用和一致性:Nacos 通过内置的集群模式和数据持久化,保证了服务注册和配置信息的高可用和一致性。
  5. 支持微服务架构:Nacos 提供了与 Spring Cloud、Dubbo 等微服务框架的集成支持,使得开发者可以方便地构建微服务架构。
4.5、服务发现开源软件-K8s

Kubernetes(简称 K8s)是 Google 开源的一款容器编排平台,用于自动化部署、扩展和管理容器化应用程序。Kubernetes 的主要特点包括:

  1. 简单易用:Kubernetes 提供了一套丰富且易用的 API 和命令行工具,使得开发者可以方便地管理和操作容器。
  2. 服务发现与负载均衡:Kubernetes 可以自动为容器分配 IP 地址和 DNS 名称,并且可以在容器之间进行负载均衡。
  3. 自动部署与回滚:Kubernetes 可以根据预定义的策略自动部署和更新应用,如果新版本的应用出现问题,还可以自动回滚到旧版本。
  4. 横向扩展:Kubernetes 可以根据 CPU 使用率或其他预定义的指标自动扩展应用。
  5. 自我修复:Kubernetes 可以自动替换、杀死、重启不健康的容器,保证服务的可用性。
  6. 密钥与配置管理:Kubernetes 可以管理和保护敏感信息,如密码、OAuth 令牌、SSH 密钥等,并且可以在不重建镜像的情况下更新应用配置。

因此,Kubernetes 是一个非常适合用于构建和运行分布式系统的容器编排平台。

4.6、服务发现的未来发展趋势

服务发现作为微服务架构中的关键组件,其未来的发展趋势可能包括以下几个方面:

  1. 自动化:随着云计算和容器技术的发展,服务的部署和扩缩容越来越自动化,服务发现也需要支持自动化,能够自动感知服务的变化并更新服务的状态;
  2. 多云和混合云:越来越多的企业选择使用多云或混合云环境,服务发现需要能够跨越多个云平台和数据中心,提供统一的服务视图;
  3. 安全:随着微服务的广泛应用,服务之间的通信安全越来越重要,服务发现需要能够支持服务的身份验证和授权,防止未授权的服务访问;
  4. 规模化:随着微服务数量的增加,服务发现需要能够支持大规模的服务管理,提供高效的服务查询和更新能力;
  5. 标准化:目前服务发现的实现方式各异,缺乏统一的标准,未来可能会出现一些服务发现的标准或规范,以促进不同的服务发现系统之间的互操作性;
  6. 集成性:服务发现可能会与其他的系统管理和监控工具更紧密地集成,提供更全面的服务管理能力。

以上是对服务发现未来发展趋势的一些预测,具体的发展情况还需要根据技术和市场的变化来观察。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-09-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、服务发现简介
    • 1.1、微服务架构的基本概念
      • 1.2、服务发现的基本概念
        • 1.3、服务发现在微服务架构中的重要性
        • 2、服务发现的工作原理
          • 2.1、服务注册
            • 2.2、服务查找
              • 2.3、负载均衡
                • 2.4、服务监测
                  • 2.5、健康检查
                    • 2.6、动态更新
                      • 2.7、各种协议的优缺点
                      • 3、服务发现的实现
                        • 3.1、服务发现提供者实现
                          • 3.2、服务发现消费者实现
                            • 3.3、服务发现注册中心实现
                              • 3.4、Java实现注册中心简单案例
                              • 4、服务发现的实际应用案例
                                • 4.1、服务发现开源软件-Eureka
                                  • 4.2、服务发现开源软件-Etcd
                                    • 4.3、服务发现开源软件-ZooKeeper
                                      • 4.4、服务发现开源软件-Nacos
                                        • 4.5、服务发现开源软件-K8s
                                          • 4.6、服务发现的未来发展趋势
                                          相关产品与服务
                                          负载均衡
                                          负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
                                          领券
                                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档