Spring Cloud Alibaba 之 服务治理:Nacos 如何实现微服务服务治理

SpringCloud Alibaba 专栏收录该内容
23 篇文章 1 订阅

前文我们学习了通用的微服务架构应包含哪些组件以及 Spring Cloud Alibaba 生态中对应的技术实现,其中整个架构体系最核心的组件是服务注册中心 Alibaba Nacos。本讲我们就对 Nacos 展开探讨,学习它的使用办法。在本讲我们会讲解三方面内容:

  • 介绍 Nacos 注册中心的特性;

  • 微服务如何在 Nacos 进行注册登记;

  • Nacos 注册中心的心跳机制与健康检查。

Nacos 注册中心的特性

我们以现实业务为例,某超市会员线上购物送等额积分,此积分在下次购物时可抵用现金,其中涉及订单服务、会员服务、积分服务等多个微服务模块。

在以往单实例情况下,服务间通常采用点对点通信,即采用 IP+端口+接口的形式直接调用。但考虑避免单点负载压力过大以及高可用的性能要求,通常会部署多实例节点保障系统的性能,但增加多实例后,调用方该如何选择哪个服务提供者进行处理呢?还有当服务提供者出现故障后,如何将后续请求转移到其他可用实例上呢?面对这些问题,微服务架构必须要引入注册中心对所有服务实例统一注册管理、有组织地进行健康检查来保障服务的可用性。

所有服务实例向注册中心登记

在 Spring Cloud Alibaba 生态中,由 Nacos 中间件承担注册中心职责,需要独立部署。下面我们先来认识一下 Nacos。

Nacos 官方地址为https://nacos.io/zh-cn/index.html。由阿里开源,官方定义为:

一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

Nacos 官方介绍

Nacos 具备以下职能:

  • 服务发现及管理;

  • 动态配置服务;

  • 动态 DNS 服务。

下图是Nacos 的核心特征:

Nacos 的核心特性

因为官网有完整的功能介绍,这里不再赘述。

Nacos 的快速部署

在微服务架构中,Nacos 注册中心处于核心地位,通常我们会采用高性能服务器独立部署。下面我来演示 Nacos 的部署过程。

环境准备

Nacos 同时支持 Windows 与 Linux 系统。因大多数服务器会选择安装 Linux 操作系统,为了模拟真实环境,建议你搭建一个 CentOS 7/8 的虚拟机,我这里的服务器地址为:192.168.31.102。Nacos 采用 Java 进行开发,要求 JDK8+,如果 CentOS 系统中没有安装 JDK,可使用下面流程进行基础环境准备。

  • 利用 yum 命令安装 OpenJDK 8。
yum -y install java-1.8.0-openjdk-devel.x86_64
#安装成功后验证Java版本
java -version

Nacos 要求 JDK8 以上版本

Nacos 要求 JDK8 以上版本

  • *配置 JAVA_HOME 环境变量。

安装后 JDK 不要忘记设置 JAVA_HOME 环境变量,OpenJDK 默认安装在 /usr/lib/jvm/ 路径下,之后通过编辑 profile 设置 JAVA_HOME 环境变量。

[root@server-1 ~]# vim /etc/profile
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.272.b10-1.el7_9.x86_64
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
[root@server-1 ~]# source /etc/profile

最后要确认 JAVA_HOME 环境变量是否配置正确。

[root@server-1 ~]# echo $JAVA_HOME
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.272.b10-1.el7_9.x86_64
JDK安装后,正式进入 Nacos 的安装过程。

安装过程

  • 第一步,访问 Nacos GitHub:https://github.com/alibaba/nacos/releases/获取 Nacos 最新版安装包 nacos-server-1.4.0.tar.gz。

  • 第二步,上传 nacos-server-1.4.0.tar.gz 到 CentOS 系统,对安装包解压缩。

root@server-1 local]#  tar -xvf nacos-server-1.4.0.tar.gz

解压后 Nacos 目录结构如下。

bin:保存启用/关闭 Nacos Server 脚本;

conf:Nacos Server 配置目录;

data:Nacos 数据目录;

logs:存放日志目录;

target:Nacos Jar 包存放目录;
  • 第三步,以单点方式启动 Nacos。
[root@server-1 local]# cd nacos/bin
[root@server-1 bin]# sh startup.sh -m standalone

启动日志如下:

nacos is starting with standalone
nacos is starting, you can check the /usr/local/nacos/nacos/logs/start.out

默认 Nacos 以后台模式启动,利用 tail 命令查看启动日志。可以看到 Nacos 默认端口为 8848,下面日志说明 Nacos 单机模式已启动成功。

[root@server-1 bin]# tail -f /usr/local/nacos/logs/start.out
2020-12-06 21:03:18,759 INFO Tomcat started on port(s): 8848 (http) with context path '/nacos'
2020-12-06 21:03:18,766 INFO Nacos Log files: /usr/local/nacos/nacos/logs
2020-12-06 21:03:18,766 INFO Nacos Log files: /usr/loca/nacos/nacos/conf
2020-12-06 21:03:18,766 INFO Nacos Log files: /usr/local/nacos/nacos/data
2020-12-06 21:03:18,767 INFO Nacos started successfully in stand alone mode. use embedded storage
  • 第四步,默认 CentOS 系统并没有对外开放 7848/8848 端口,需要设置防火墙对 7848/8848 端口放行。

其中,8848 端口是 Nacos 对客户端提供服务的端口,7848 是 Nacos 集群通信端口,用于Nacos 集群间进行选举,检测等。

[root@server-1 bin]# firewall-cmd --zone=public --add-port=8848/tcp --permanentsuccess[root@server-1 bin]# firewall-cmd --zone=public --add-port=7848/tcp --permanentsuccess[root@server-1 bin]# firewall-cmd  --reloadsuccess

此时,Nacos 已单机部署完毕。

  • 第五步,进入 Nacos 管理界面,打开浏览器,地址栏输入:

http://192.168.31.102:8848/nacos

其中 192.168.31.102 就是 Nacos 服务器的IP地址,端口号 8848。

Nacos 控制台

管理界面默认用户名与密码均为nacos,提交后进入首页。点击左侧菜单“服务管理->服务列表”,这个功能用于查看已注册微服务列表。

已注册服务列表

目前因为没有任何微服务注册,右侧服务列表是空的。那如何让微服务在 Nacos 中注册呢?下一小节咱们继续讲解。

微服务如何接入 Nacos

Spring Cloud Alibaba 作为 Spring Cloud 子项目,开发框架仍基于 SpringBoot,只是在构建项目时需要选择不同的 starter 接入注册中心,下面我们通过实操完成微服务与 Nacos 服务器的接入工作。

开发工具强烈推荐 IDEA Ultimate,Ultimate 内置 SpringBoot 工程向导,可以非常方便地实现 Spring Cloud 微服务的快速创建。

Nacos Ultimate

    1. 创建新工程,工程类型选择 Spring Initializr。
      下图是 SpringBoot 工程向导,右侧选中 Custom,写入阿里云地址http://start.aliyun.com,默认的 https://start.spring.io。 这里需要连接 spring 官方服务器,因为网络原因经常无法访问,所以采用国内阿里云镜像生成工程初始代码。

Spring Initializr 工程向导

Project Metadata 面板,设置 Maven Group 与 Artifact,一般 Artifact 即为微服务名称,约定俗成以 service 单词结尾。

    1. 在向导后面的依赖页面,要接入 Nacos 有一项是必选的,请大家注意。
      Spring Cloud Alibaba -> Nacos Service Discovery。

Nacos Service Discovery 是在当前SpringBoot工程内置 Nacos 客户端,在微服务应用启动时通过 Nacos 客户端向 Nacos 服务器发送注册信息。

引入 Nacos 客户端

    1. 工程创建成功,打开 pom.xml 文件,确认 Maven 依赖 nacos-discovery,说明服务已内置 Nacos 客户端成功。

确认依赖

此外,我们需要在当前微服务增加 Spring-Web 依赖。因为微服务默认通过 RESTful API 对外暴露接口,增加 Spring-Web 会在应用中内嵌 Tomcat,使微服务具备 HTTP 响应能力。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
    1. 在 application.properties 配置 Nacos 注册中心通信地址。
# 应用名称,默认也是在微服务中注册的微服务 ID
spring.application.name=sample-service
# 配置 Nacos 服务器的IP地址
spring.cloud.nacos.discovery.server-addr=192.168.31.102:8848
#连接 Nacos 服务器使用的用户名、密码,默认为 nacos
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discvery.password=nacos
#微服务提供Web服务的端口号
server.port=9000
    1. 启动 SampleService 工程,在启动日志最后三句清晰的说明注册已成功。

      #Web 服务端口号 9000
      INFO 14188 o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 9000 (http) with context path ''
      #微服务向 Nacos 注册成功,微服务 ID:sample-service
      INFO 14188  c.a.c.n.registry.NacosServiceRegistry    : nacos registry, DEFAULT_GROUP sample-service 192.168.47.1:9000 register finished
      #微服务启动成功
      INFO 14188  c.l.s.SampleServiceApplication           : Started SampleServiceApplication in 4.911 seconds (JVM running for 6.039)
      
    1. 浏览器打开http://192.168.31.102:8848/nacos,查看服务列表时发现 sample-service 服务已出现

sample-service 实例注册成功

点击列表右侧“详情按钮”就会出现详细信息,在服务详情下清晰列出 sample-service 服务目前可用实例的 IP 及服务端口。

详情查看服务实例明细

到这里我们已完成了微服务向 Nacos 注册登记,因为 SpringBoot 为我们高度封装了注册过程。为了你更透彻理解 Nacos,下面我来介绍 Nacos 注册过程背后的原理。

Nacos 注册中心的心跳机制

讲到这里,你可能会有疑问:无论是部署 Nacos 服务器还是构建 Sample-Service 微服务,只用了几行代码便实现在 Nacos 注册登记。这一切背后,到底是如何实现的?这一小节我将为你答疑解惑。

下图阐述了微服务与 Nacos 服务器之间的通信过程。在微服务启动后每过5秒,会由微服务内置的 Nacos 客户端主动向 Nacos 服务器发起心跳包(HeartBeat)。心跳包会包含当前服务实例的名称、IP、端口、集群名、权重等信息。

Nacos 注册中心的心跳机制

如果你开启微服务 Debug 日志,会清晰地看到每 5 秒一个心跳请求被发送到 Nacos 的 /nacos/v1/ns/instance/beat 接口,该请求会被 Nacos 服务器内置的 naming 模块处理。

23:11:23.826 DEBUG 10720 --- [ing.beat.sender] s.n.www.protocol.http.HttpURLConnection  : sun.net.www.MessageHeader@665891d213 pairs: {PUT /nacos/v1/ns/instance/beat?app=unknown&serviceName=DEFAULT_GROUP%40%40sample-service&namespaceId=public&port=9000&clusterName=DEFAULT&ip=192.168.47.1 HTTP/1.1: null}{Content-Type: application/x-www-form-urlencoded}{Accept-Charset: UTF-8}{Accept-Encoding: gzip,deflate,sdch}{Content-Encoding: gzip}{Client-Version: 1.3.2}{User-Agent: Nacos-Java-Client:v1.3.2}{RequestId: 6447aa06-9d70-41ea-83ef-cd27af1d3422}{Request-Module: Naming}{Host: 192.168.31.102:8848}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}{Content-Length: 326}
23:11:28.837 DEBUG 10720 --- [ing.beat.sender] s.n.www.protocol.http.HttpURLConnection  : sun.net.www.MessageHeader@5f00479a12 pairs: {PUT /nacos/v1/ns/instance/beat?app=unknown&serviceName=DEFAULT_GROUP%40%40sample-service&namespaceId=public&port=9000&clusterName=DEFAULT&ip=192.168.47.1 HTTP/1.1: null}{Content-Type: application/x-www-form-urlencoded}{Accept-Charset: UTF-8}{Accept-Encoding: gzip,deflate,sdch}{Content-Encoding: gzip}{Client-Version: 1.3.2}{User-Agent: Nacos-Java-Client:v1.3.2}{RequestId: 9fdf2264-9704-437f-bd34-7c9ee5e0be41}{Request-Module: Naming}{Host: 192.168.31.102:8848}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}
23:11:38.847 DEBUG 10720 --- [ing.beat.sender] s.n.www.protocol.http.HttpURLConnection  : sun.net.www.MessageHeader@3521283812 pairs: {PUT /nacos/v1/ns/instance/beat?app=unknown&serviceName=DEFAULT_GROUP%40%40sample-service&namespaceId=public&port=9000&clusterName=DEFAULT&ip=192.168.47.1 HTTP/1.1: null}{Content-Type: application/x-www-form-urlencoded}{Accept-Charset: UTF-8}{Accept-Encoding: gzip,deflate,sdch}{Content-Encoding: gzip}{Client-Version: 1.3.2}{User-Agent: Nacos-Java-Client:v1.3.2}{RequestId: ccb6a586-897f-4036-9c0d-c614e2ff370a}{Request-Module: Naming}{Host: 192.168.31.102:8848}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}

naming 模块在接收到心跳包后,会按下图逻辑处理心跳包并返回响应:

    1. naming 模块收到心跳包,首先根据 IP 与端口判断 Nacos 是否存在该服务实例?如果实例信息不存在,在 Nacos 中注册登记该实例。而注册的本质是将新实例对象存储在“实例 Map”集合中;
    1. 如果实例信息已存在,记录本次心跳包发送时间;
    1. 设置实例状态为“健康”;
    1. 推送“微服务状态变更”消息;
    1. naming 模块返回心跳包时间间隔。

到这里一次完整的心跳包处理已完成。

Nacos Server 对心跳包的处理过程

那 Nacos 又是如何将无效实例从可用实例中剔除呢?Nacos Server 内置的逻辑是每过 20 秒对“实例 Map”中的所有“非健康”实例进行扫描,如发现“非健康”实例,随即从“实例 Map”中将该实例删除。

docker部署单机模式

docker run -d -p 8848:8848 --env MODE=standalone --env SPRING_DATASOURCE_PLATFORM=mysql --env MYSQL_SERVICE_HOST=192.168.1.151 --env MYSQL_SERVICE_PORT=3306 --env MYSQL_SERVICE_DB_NAME=nacos --env MYSQL_SERVICE_USER=root --env MYSQL_SERVICE_PASSWORD=123456 --env JVM_XMS=512m --env JVM_XMX=512m --env JVM_XMN=256m --env JVM_MS=64m --env JVM_MMS=160M --name nacos  nacos/nacos-server

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

<span>Spring Cloud Alibaba </span><span>致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服<br /> 务的必需组件,方便开发者通过 </span><span>Spring Cloud </span><span>编程模型轻松使用这些组件来开发分布式应用服务。<br /> 依托 </span><span>Spring Cloud Alibaba</span><span>,您只需要添加一些注解和少量配置,就可以将 </span><span>Spring Cloud </span><span>应用接<br /></span> <p> <span>入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。</span> </p> <p> <span><span>主要功能<br /></span>服务限流降级<span>默认支持 </span><span>WebServlet</span><span>、 </span><span>WebFlux</span><span>, </span><span>OpenFeign</span><span>、 </span><span>RestTemplate</span><span>、 </span><span>Spring Cloud<br /> Gateway</span><span>, </span><span>Zuul</span><span>, </span><span>Dubbo </span><span>和 </span><span>RocketMQ </span><span>限流降级功能的接入,可以在运行时通过控制台实时修<br /> 改限流降级规则,还支持查看限流降级 </span><span>Metrics </span><span>监控。<br /></span>服务注册与发现<span>适配 </span><span>Spring Cloud </span><span>服务注册与发现标准,默认集成了 </span><span>Ribbon </span><span>的支持。<br /></span>分布式配置管理<span>支持分布式系统中的外部化配置,配置更改时自动刷新。<br /></span>消息驱动能力<span>基于 </span><span>Spring Cloud Stream </span><span>为微服务应用构建消息驱动能力。<br /></span>分布式事务<span>使用 </span><span>@GlobalTransactional </span><span>注解, 高效并且对业务零侵入地解决分布式事务问题。<br /></span>阿里云对象存储<span>阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任<br /> 何时间、任何地点存储和访问任意类型的数据。<br /></span>分布式任务调度<span>提供秒级、精准、高可靠、高可用的定时(基于 </span><span>Cron </span><span>表达式)任务调度服务。<br /> 同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有<br /></span><span>Worker</span><span>(</span><span>schedulerx-client</span><span>)上执行。<br /></span>阿里云短信服务<span>覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建<br /> 客户触达通道</span> <br /><br /></span> </p>
相关推荐
<p> <span>课程目录如下</span> </p> <p> <span style="color:#333333;">第一章 课程介绍</span> </p> <p> <span style="color:#333333;"></span><span style="color:#333333;">第二章 微服务架构及注册中心eureka与nocos区别</span> </p> <p> <span style="color:#333333;"></span><span style="color:#333333;">第三章 nacos官网介绍及单机部署</span> </p> <p> <span style="color:#333333;"></span><span style="color:#333333;">第四章 nacos集群部署</span> </p> <p> <span style="color:#333333;"></span><span style="color:#333333;">第五章 nacos控制台介绍</span> </p> <p> <span style="color:#333333;"></span><span style="color:#333333;">第六章 注册中心nacos服务注册与发现)</span> </p> <p> <span style="color:#333333;"></span><span style="color:#333333;">第七章 Http客户端及负载均衡springcloud openfeign</span> </p> <p> <span style="color:#333333;"></span><span style="color:#333333;">第八章 nacos配置中心</span> </p> <p> <span style="color:#333333;"></span><span style="color:#333333;">第九章 课程总结</span> </p> <p> <span style="color:#333333;"><br /></span> </p> <p> <span style="color:#333333;"><span>Alibaba nacos于2018年7月开源,并开始逐步拥抱springcloud社区,alibaba微服务框架大有超越势,目前热度非常高,其中注册中心nacos就像人心脏,值得分享与学习下,</span></span><span style="color:#333333;">课件markdown资料及课程源码都已经上传。</span> </p> <p> <span style="color:#333333;"><br /></span> </p>
<p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;">本套2021新版视频教程为SpringCloud Hoxton版和SpringCloud alibaba,内容涵盖目前流行的分布式微服务架构的技术栈。</span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;">教程重点讲解了SpringCloud各种组件停止更新进入维护阶段后,后续技术组件的升级和替换策略及方案选型,重点讲解了阿里巴巴新的Nacos、Sentinel、Seata等技术,分享了服务降级、服务熔断、服务限流、hotkey控制、分布式统一配置管理、分布式全局事务控制、RabbitMQ与Stream整合、Nacos和Nginx配置高可用集群等技术,本教程帮助大家强化分布式微服务架构思维,带大家进入互联网微服架构的世界!</span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;">课程大纲</span></strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><img src="https://img-bss.csdnimg.cn/202103121606389667.png" alt="" /></span></strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;">微服务架构生态</span></strong></span></strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><img src="https://img-bss.csdnimg.cn/202103121607127250.png" alt="" /></span></strong></span></strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;">课程部分讲义</span></strong></span></strong></span></strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><img src="https://img-bss.csdnimg.cn/202103121607306150.png" alt="" /></span></strong></span></strong></span></strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><img src="https://img-bss.csdnimg.cn/202103121607428230.gif" alt="" /></span></strong></span></strong></span></strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><img src="https://img-bss.csdnimg.cn/202103121607552280.gif" alt="" /></span></strong></span></strong></span></strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><img src="https://img-bss.csdnimg.cn/202103121608059000.gif" alt="" /></span></strong></span></strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><img src="https://img-bss.csdnimg.cn/202103121608173909.png" alt="" /></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><img src="https://img-bss.csdnimg.cn/202103121608283812.gif" alt="" /></span></strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #404040;"><strong style="margin: 0px; padding: 0px; color: #313d54;"><span style="margin: 0px; padding: 0px; color: #404040;"><img src="https://img-bss.csdnimg.cn/202103121608426911.png" alt="" /></span></strong></span></p>
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值