一、核心概念总览

Service Mesh(服务网格)是一种基础设施层,它处理服务间通信,提供负载均衡、服务发现、流量管理、安全、可观测性等能力,而无需修改应用代码。

双平面架构

text

复制

下载

┌─────────────────────────────────────────────────────────────┐
│                   应用服务层                                  │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐              │
│  │  Service │    │  Service │    │  Service │              │
│  │    A     │    │    B     │    │    C     │              │
│  └──────────┘    └──────────┘    └──────────┘              │
│        │               │               │                    │
└────────┼───────────────┼───────────────┼────────────────────┘
         │               │               │
         ▼               ▼               ▼
┌─────────────────────────────────────────────────────────────┐
│                 数据平面 (Data Plane)                        │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐              │
│  │  Sidecar │    │  Sidecar │    │  Sidecar │              │
│  │  Proxy   │    │  Proxy   │    │  Proxy   │              │
│  └──────────┘    └──────────┘    └──────────┘              │
│        │               │               │                    │
└────────┼───────────────┼───────────────┼────────────────────┘
         │               │               │
         ▼               ▼               ▼
┌─────────────────────────────────────────────────────────────┐
│                 控制平面 (Control Plane)                     │
│  ┌──────────────────────────────────────────────┐          │
│  │  配置分发 │ 服务发现 │ 证书管理 │ 策略执行   │          │
│  └──────────────────────────────────────────────┘          │
│                    │           │           │                │
│         ┌──────────┴──┐ ┌──────┴─────┐ ┌──┴──────────┐     │
│         │  Istio Pilot│ │  Istio     │ │  Istio      │     │
│         │             │ │  Citadel   │ │  Galley     │     │
│         └─────────────┘ └────────────┘ └─────────────┘     │
└─────────────────────────────────────────────────────────────┘

二、数据平面(Data Plane)深度解析

1. 核心职责:处理实际的数据流

java

复制

下载

// 模拟Sidecar代理的核心功能架构
public class SidecarProxy {
    // 1. 网络拦截
    private TrafficInterceptor interceptor;
    
    // 2. 流量管理
    private TrafficManager trafficManager;
    
    // 3. 可观测性收集
    private TelemetryCollector telemetry;
    
    // 4. 安全组件
    private SecurityEnforcer security;
    
    public void processRequest(Request request) {
        // 步骤1: TLS终止/发起
        security.handleTLS(request);
        
        // 步骤2: 收集指标和日志
        telemetry.collectRequestMetrics(request);
        
        // 步骤3: 应用路由规则
        String targetService = trafficManager.route(request);
        
        // 步骤4: 负载均衡选择实例
        String instance = trafficManager.loadBalance(targetService);
        
        // 步骤5: 执行重试、超时、熔断策略
        Response response = trafficManager.executeWithResilience(
            () -> forwardToInstance(request, instance)
        );
        
        // 步骤6: 收集响应指标
        telemetry.collectResponseMetrics(response);
        
        return response;
    }
}

2. 关键组件:Envoy Proxy详解

Envoy是最流行的数据平面实现,让我们看其核心功能:

yaml

复制

下载

# envoy.yaml - 展示Envoy核心配置
static_resources:
  listeners:
  - name: http_listener
    address:
      socket_address: { address: 0.0.0.0, port_value: 15001 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          
          # HTTP过滤器链
          http_filters:
          - name: envoy.filters.http.router
          - name: envoy.filters.http.fault  # 故障注入
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault
              delay:
                percentage:
                  numerator: 10
                  denominator: HUNDRED
                fixed_delay: 5s
          
          # 路由配置
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route:
                  cluster: service_b
                  retry_policy:
                    retry_on: "5xx"
                    num_retries: 3
                  timeout: 10s
  
  # 集群定义
  clusters:
  - name: service_b
    connect_timeout: 0.25s
    type: EDS  # 动态端点发现
    lb_policy: ROUND_ROBIN
    circuit_breakers:
      thresholds:
        - priority: DEFAULT
          max_connections: 100
          max_requests: 1000

 篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc

需要全套面试笔记及答案
【点击此处即可/免费获取】​​​

3. 数据平面核心功能代码实现

java

复制

下载

// 流量拆分(金丝雀发布)实现示例
public class TrafficSplitter {
    private Map<String, Integer> versionWeights;
    
    public String selectVersion(HttpRequest request) {
        // 基于权重的随机选择
        int totalWeight = versionWeights.values().stream().mapToInt(i -> i).sum();
        int random = new Random().nextInt(totalWeight);
        
        int cumulative = 0;
        for (Map.Entry<String, Integer> entry : versionWeights.entrySet()) {
            cumulative += entry.getValue();
            if (random < cumulative) {
                return entry.getKey();
            }
        }
        return "v1"; // 默认版本
    }
    
    // 基于Header的流量路由
    public String routeBasedOnHeader(HttpRequest request) {
        if (request.getHeader("x-user-type") != null) {
            if (request.getHeader("x-user-type").equals("premium")) {
                return "premium-cluster";
            }
        }
        return "standard-cluster";
    }
}

// 熔断器实现
public class CircuitBreaker {
    private enum State { CLOSED, OPEN, HALF_OPEN }
    private State currentState = State.CLOSED;
    private long lastFailureTime = 0;
    private int failureCount = 0;
    private final int failureThreshold = 5;
    private final long resetTimeout = 60000; // 60秒
    
    public <T> T execute(Supplier<T> operation) {
        if (currentState == State.OPEN) {
            if (System.currentTimeMillis() - lastFailureTime > resetTimeout) {
                currentState = State.HALF_OPEN;
            } else {
                throw new CircuitBreakerOpenException();
            }
        }
        
        try {
            T result = operation.get();
            if (currentState == State.HALF_OPEN) {
                currentState = State.CLOSED;
                failureCount = 0;
            }
            return result;
        } catch (Exception e) {
            handleFailure();
            throw e;
        }
    }
    
    private void handleFailure() {
        failureCount++;
        if (failureCount >= failureThreshold) {
            currentState = State.OPEN;
            lastFailureTime = System.currentTimeMillis();
        }
    }
}

三、控制平面(Control Plane)深度解析

1. 核心职责:管理与配置

java

复制

下载

// 控制平面核心架构示例
public class ControlPlane {
    // 配置管理
    private ConfigurationManager configManager;
    
    // 服务发现
    private ServiceDiscovery serviceDiscovery;
    
    // 证书管理
    private CertificateManager certManager;
    
    // 策略分发
    private PolicyDistributor policyDistributor;
    
    public void initialize() {
        // 1. 监听Kubernetes API(服务变化)
        watchKubernetesServices();
        
        // 2. 管理证书和密钥
        manageCertificates();
        
        // 3. 分发配置到所有Sidecar
        distributeConfigurations();
        
        // 4. 收集遥测数据
        collectTelemetry();
    }
    
    private void distributeConfigurations() {
        // 将路由规则、策略等转换为Envoy配置
        EnvoyConfiguration config = convertToEnvoyConfig(
            getRoutingRules(),
            getSecurityPolicies(),
            getObservabilityConfig()
        );
        
        // 通过xDS API分发到所有数据平面代理
        xdsServer.pushConfiguration(config);
    }
}

2. Istio控制平面组件详解

java

复制

下载

// Pilot - 服务发现和流量管理
public class PilotComponent {
    private KubernetesClient k8sClient;
    private ConfigStore configStore;
    private DiscoveryServer discoveryServer;
    
    public void reconcile() {
        // 从K8s获取服务信息
        List<Service> services = k8sClient.listServices();
        List<Endpoint> endpoints = k8sClient.listEndpoints();
        
        // 获取用户定义的流量规则(VirtualService, DestinationRule)
        List<VirtualService> virtualServices = configStore.getVirtualServices();
        List<DestinationRule> destinationRules = configStore.getDestinationRules();
        
        // 生成Envoy配置
        EnvoyConfiguration config = generateEnvoyConfig(
            services, endpoints, virtualServices, destinationRules
        );
        
        // 通过xDS API推送到Envoy
        discoveryServer.push(config);
    }
}

// Citadel - 安全组件
public class CitadelComponent {
    public Certificate generateCertificate(String serviceAccount) {
        // 1. 生成密钥对
        KeyPair keyPair = generateKeyPair();
        
        // 2. 创建CSR
        CertificateSigningRequest csr = createCSR(serviceAccount, keyPair);
        
        // 3. 签名证书
        X509Certificate certificate = ca.sign(csr);
        
        // 4. 分发到Sidecar
        distributeToSidecar(serviceAccount, certificate, keyPair.getPrivate());
        
        return certificate;
    }
    
    // 自动证书轮换
    public void rotateCertificates() {
        List<ServiceAccount> accounts = getAllServiceAccounts();
        for (ServiceAccount account : accounts) {
            if (shouldRotate(account)) {
                generateCertificate(account.getName());
            }
        }
    }
}

3. xDS API协议详解

xDS是控制平面和数据平面之间的通信协议:

protobuf

复制

下载

// protobuf定义示例(简化版)
message DiscoveryRequest {
    string node_id = 1;  // Envoy实例ID
    repeated string resource_names = 2; // 请求的资源
    string type_url = 3;  // 资源类型
    string version_info = 4; // 当前版本
}

message DiscoveryResponse {
    string version_info = 1;
    repeated google.protobuf.Any resources = 2;
    string type_url = 3;
}

// 具体的资源配置
message Cluster {
    string name = 1;
    ClusterType type = 2;
    repeated LoadBalancingPolicy lb_policies = 3;
    CircuitBreakers circuit_breakers = 4;
}

message RouteConfiguration {
    string name = 1;
    repeated VirtualHost virtual_hosts = 2;
}

四、双平面交互流程

完整请求流程示例

java

复制

下载

public class ServiceMeshRequestFlow {
    
    // 1. 服务A发起请求
    public void serviceAToB() {
        // 应用代码只关心业务逻辑
        Response response = httpClient.get("http://service-b/api/data");
        // 实际流量被Sidecar拦截处理
    }
    
    // 2. Sidecar拦截和处理(数据平面)
    public class ServiceASidecar {
        public Response interceptRequest(Request request) {
            // a) mTLS加密
            TLSContext tls = security.establishMTLS("service-b");
            
            // b) 服务发现 - 从控制平面获取端点
            List<Endpoint> endpoints = xdsClient.getEndpoints("service-b");
            
            // c) 负载均衡选择
            Endpoint selected = loadBalancer.select(endpoints);
            
            // d) 应用路由规则
            if (shouldApplyCanary(request)) {
                selected = selectCanaryEndpoint(request);
            }
            
            // e) 收集指标
            metrics.recordOutboundRequest(request);
            
            // f) 发送请求(带重试、熔断)
            return resilience.executeWithRetry(() -> 
                sendRequest(request, selected, tls)
            );
        }
    }
    
    // 3. 控制平面的配置推送
    public class ControlPlanePush {
        public void onConfigChange() {
            // 当VirtualService变更时
            VirtualService newConfig = getUpdatedVirtualService();
            
            // 转换为xDS资源
            RouteConfiguration routeConfig = convertToRouteConfig(newConfig);
            
            // 推送到所有相关的Envoy实例
            xdsServer.pushToSubscribers("service-a", routeConfig);
            
            // Envoy热加载配置,无需重启
        }
    }
}

五、实战:实现简易Service Mesh

1. 简易控制平面实现

java

复制

下载

@RestController
public class SimpleControlPlane {
    
    // 存储配置
    private Map<String, ServiceConfig> configStore = new ConcurrentHashMap<>();
    
    // xDS端点
    @GetMapping("/v3/discovery:{type}")
    public DiscoveryResponse discovery(
            @PathVariable String type,
            @RequestBody DiscoveryRequest request) {
        
        String serviceName = extractServiceName(request.getNodeId());
        List<Resource> resources;
        
        switch (type) {
            case "clusters":
                resources = generateClusters(serviceName);
                break;
            case "endpoints":
                resources = generateEndpoints(serviceName);
                break;
            case "routes":
                resources = generateRoutes(serviceName);
                break;
            default:
                resources = Collections.emptyList();
        }
        
        return DiscoveryResponse.newBuilder()
            .setVersionInfo(getVersion())
            .addAllResources(resources)
            .setTypeUrl(type)
            .build();
    }
    
    // 配置更新接口
    @PostMapping("/config")
    public void updateConfig(@RequestBody ServiceConfig config) {
        configStore.put(config.getServiceName(), config);
        notifySubscribers(config.getServiceName());
    }
    
    private void notifySubscribers(String serviceName) {
        // 通知所有订阅了此服务配置的Sidecar
        subscribers.get(serviceName).forEach(sidecar -> {
            sidecar.onConfigUpdate();
        });
    }
}

 篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc

需要全套面试笔记及答案
【点击此处即可/免费获取】​​​

2. 简易数据平面实现

java

复制

下载

public class SimpleSidecarProxy {
    
    private final ControlPlaneClient controlPlane;
    private final HttpClient httpClient;
    private volatile Config currentConfig;
    
    public SimpleSidecarProxy(String serviceName) {
        this.controlPlane = new ControlPlaneClient();
        this.httpClient = HttpClient.newBuilder()
            .executor(Executors.newVirtualThreadPerTaskExecutor())
            .build();
        
        // 初始化时从控制平面拉取配置
        initializeConfig(serviceName);
        
        // 启动配置监听
        startConfigWatch();
    }
    
    public <T> T intercept(Supplier<T> operation, HttpRequest request) {
        // 1. 检查熔断器
        if (circuitBreaker.isOpen()) {
            throw new CircuitBreakerOpenException();
        }
        
        // 2. 应用流量策略
        request = applyRoutingPolicies(request);
        
        // 3. 收集指标
        long startTime = System.nanoTime();
        try {
            T result = operation.get();
            metrics.recordSuccess(System.nanoTime() - startTime);
            return result;
        } catch (Exception e) {
            metrics.recordFailure(e);
            circuitBreaker.recordFailure();
            throw e;
        }
    }
    
    private void initializeConfig(String serviceName) {
        // 通过xDS获取初始配置
        currentConfig = controlPlane.fetchConfig(serviceName);
        
        // 应用配置
        applyConfig(currentConfig);
    }
    
    private void startConfigWatch() {
        // 长轮询配置变更
        Executors.newSingleThreadExecutor().submit(() -> {
            while (true) {
                try {
                    Config newConfig = controlPlane.watchConfig();
                    if (!newConfig.equals(currentConfig)) {
                        currentConfig = newConfig;
                        applyConfig(newConfig);
                    }
                } catch (Exception e) {
                    Thread.sleep(5000); // 失败后重试
                }
            }
        });
    }
}

3. Kubernetes Operator示例

yaml

复制

下载

# Service Mesh自定义资源定义
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: trafficpolicies.mesh.example.com
spec:
  group: mesh.example.com
  versions:
    - name: v1alpha1
      served: true
      storage: true
  scope: Namespaced
  names:
    plural: trafficpolicies
    singular: trafficpolicy
    kind: TrafficPolicy
---
apiVersion: mesh.example.com/v1alpha1
kind: TrafficPolicy
metadata:
  name: canary-release
spec:
  selector:
    app: product-service
  rules:
  - destination:
      host: product-service
      subset: v1
    weight: 90
  - destination:
      host: product-service  
      subset: v2
    weight: 10
    match:
    - headers:
        x-canary: "true"

java

复制

下载

// Operator实现
@Controller
public class TrafficPolicyOperator {
    
    @KubernetesResource("trafficpolicies.mesh.example.com/v1alpha1")
    public void onTrafficPolicy(ResourceEvent<TrafficPolicy> event) {
        TrafficPolicy policy = event.getResource();
        
        // 转换为Istio配置
        VirtualService vs = convertToVirtualService(policy);
        
        // 应用到集群
        kubernetesClient.resources(VirtualService.class)
            .inNamespace(policy.getMetadata().getNamespace())
            .createOrReplace(vs);
        
        // 通知控制平面
        controlPlane.notifyConfigChange();
    }
}

六、高级特性实现

1. 分布式追踪

java

复制

下载

public class TracingInterceptor {
    
    public void interceptRequest(HttpRequest request, String serviceName) {
        // 从Header中提取或创建Trace
        String traceId = request.getHeader("x-b3-traceid");
        if (traceId == null) {
            traceId = generateTraceId();
        }
        
        String spanId = generateSpanId();
        
        // 记录Span开始
        Span span = tracer.buildSpan("http_request")
            .asChildOf(extractContext(request))
            .withTag("service", serviceName)
            .withTag("http.method", request.method())
            .start();
        
        // 添加追踪Header
        request.header("x-b3-traceid", traceId);
        request.header("x-b3-spanid", spanId);
        request.header("x-b3-parentspanid", getParentSpanId());
        
        try (Scope scope = tracer.activateSpan(span)) {
            // 执行请求
            HttpResponse response = executeRequest(request);
            
            span.setTag("http.status_code", response.statusCode());
            return response;
        } catch (Exception e) {
            span.setTag("error", true);
            span.log(e.getMessage());
            throw e;
        } finally {
            span.finish();
        }
    }
}

2. 故障注入

java

复制

下载

public class FaultInjector {
    
    public Response maybeInjectFault(HttpRequest request, FaultConfig config) {
        // 延迟故障
        if (shouldInjectDelay(config)) {
            Thread.sleep(randomDelay(config.getDelayConfig()));
        }
        
        // 中止故障
        if (shouldInjectAbort(config)) {
            return new HttpResponse(503, "Service Unavailable");
        }
        
        // 随机故障
        if (shouldInjectRandomFault(config)) {
            if (Math.random() < config.getErrorRate()) {
                throw new RuntimeException("Injected fault");
            }
        }
        
        return null; // 不注入故障
    }
    
    private boolean shouldInjectDelay(FaultConfig config) {
        // 基于Header、Cookie、百分比等条件判断
        return config.isEnabled() && 
               matchesSelector(request, config.getSelector()) &&
               Math.random() < config.getDelayPercentage();
    }
}

七、性能优化与最佳实践

1. 数据平面优化

java

复制

下载

public class OptimizedSidecar {
    
    // 使用对象池减少GC
    private final ObjectPool<Connection> connectionPool;
    
    // 使用零拷贝减少内存复制
    public void handleRequest(ByteBuffer buffer) {
        try {
            // 直接操作缓冲区,避免复制
            parseHeadersInPlace(buffer);
            
            // 使用直接内存进行转发
            ByteBuffer directBuffer = ByteBuffer.allocateDirect(buffer.remaining());
            directBuffer.put(buffer);
            directBuffer.flip();
            
            forwardWithoutCopy(directBuffer);
        } finally {
            buffer.clear();
        }
    }
    
    // 异步非阻塞IO
    public CompletableFuture<Response> handleAsync(Request request) {
        return CompletableFuture.supplyAsync(() -> {
            return processRequest(request);
        }, virtualThreadExecutor);
    }
}

2. 控制平面优化

java

复制

下载

public class OptimizedControlPlane {
    
    // 增量xDS
    public DeltaDiscoveryResponse deltaDiscovery(DeltaDiscoveryRequest request) {
        Set<String> subscribed = request.getResourceNamesSubscribeList();
        Set<String> unsubscribed = request.getResourceNamesUnsubscribeList();
        
        // 只计算变更的部分
        Map<String, Resource> changes = computeChanges(
            subscribed, unsubscribed, request.getTypeUrl()
        );
        
        return DeltaDiscoveryResponse.newBuilder()
            .addAllResources(changes.values())
            .addAllRemovedResources(computeRemoved(unsubscribed))
            .build();
    }
    
    // 配置压缩
    public byte[] compressConfig(Configuration config) {
        // 使用Protocol Buffer二进制格式
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(baos);
        config.writeTo(gzip);
        gzip.close();
        return baos.toByteArray();
    }
}

篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc

需要全套面试笔记及答案
【点击此处即可/免费获取】​​​

八、监控与运维

1. 健康检查

java

复制

下载

@Component
public class SidecarHealthChecker {
    
    @Scheduled(fixedRate = 10000)
    public void checkHealth() {
        // 检查与控制平面的连接
        boolean controlPlaneHealthy = checkControlPlane();
        
        // 检查本地资源
        boolean resourcesHealthy = checkLocalResources();
        
        // 更新健康状态
        healthIndicator.setStatus(
            controlPlaneHealthy && resourcesHealthy ? 
            Status.UP : Status.DOWN
        );
        
        // 发送心跳
        if (controlPlaneHealthy) {
            sendHeartbeat();
        }
    }
    
    // 优雅关闭
    @PreDestroy
    public void shutdown() {
        // 1. 停止接收新请求
        server.stopAcceptingRequests();
        
        // 2. 等待进行中的请求完成
        awaitOngoingRequests(30, TimeUnit.SECONDS);
        
        // 3. 关闭连接池
        connectionPool.close();
        
        // 4. 刷新指标和日志
        telemetry.flush();
    }
}

2. 可观测性集成

java

复制

下载

@Configuration
public class ObservabilityConfig {
    
    @Bean
    public MeterRegistry meterRegistry() {
        return new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
    }
    
    @Bean 
    public Tracer tracer() {
        return new JaegerTracer.Builder("sidecar-proxy")
            .withSampler(new ConstSampler(true))
            .build();
    }
    
    @Bean
    public AccessLogFilter accessLogFilter() {
        return new AccessLogFilter();
    }
}

public class MetricsCollector {
    private final MeterRegistry registry;
    private final DistributionSummary requestLatency;
    private final Counter errorCounter;
    
    public MetricsCollector(MeterRegistry registry) {
        this.registry = registry;
        this.requestLatency = DistributionSummary
            .builder("http_request_duration_seconds")
            .description("HTTP request duration in seconds")
            .register(registry);
        this.errorCounter = Counter
            .builder("http_request_errors")
            .description("HTTP request errors")
            .register(registry);
    }
    
    public void recordRequest(long durationNanos, int statusCode) {
        requestLatency.record(durationNanos / 1_000_000_000.0);
        
        registry.counter("http_requests_total",
            "status_code", String.valueOf(statusCode),
            "method", "GET")
            .increment();
        
        if (statusCode >= 500) {
            errorCounter.increment();
        }
    }
}

九、总结

数据平面 vs 控制平面对比表

方面 数据平面 控制平面
核心职责 处理实际流量 管理与配置
部署位置 每个Pod中(Sidecar) 集群级别
性能要求 低延迟、高吞吐 高可用、强一致
扩展方式 水平扩展(更多Pod) 垂直扩展或集群化
典型组件 Envoy、Linkerd-proxy Istio Pilot、Citadel
关注重点 网络性能、资源效率 配置正确性、策略一致性

关键设计模式

  1. Sidecar模式:应用与基础设施解耦

  2. 控制反转:控制平面推送配置,数据平面执行

  3. 最终一致性:配置异步传播,容忍短暂不一致

  4. 声明式API:用户声明期望状态,系统确保实际状态匹配

现代演进趋势

  1. eBPF技术:内核层服务网格,绕过Sidecar

  2. Proxyless模式:应用直接集成xDS客户端

  3. 多集群网格:跨集群的服务发现和路由

  4. AI驱动优化:基于机器学习自动调整策略

Service Mesh的双平面架构通过关注点分离,实现了基础设施的抽象和统一管理,是云原生架构的核心组件。理解其工作原理对于设计和运维现代分布式系统至关重要。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐