《大型网站技术架构 核心原理与案例分析》读书笔记

第一章 大型网站架构演化

1.大型网站架构演化发展历程

1)初始阶段的网站架构

只有一台服务器

2)应用服务和数据服务分离

使用三台服务器:应用服务器,文件服务器和数据库服务器

3)使用缓存改善网站性能

网站使用的缓存分为两类:服务器上的本地缓存和分布式缓存服务器上的远程缓存。

4)使用应用服务器集群改善网站的并发处理能力

增加服务器来分担原有服务器的访问及存储压力。通过负载均衡调度服务器,将请求分发到应用服务器集群中任何一台服务器上。

5)数据库读写分离

应用服务器在写数据的时候,访问主数据库,主数据库通过主从复制机制将数据更新同步到从数据库,当应用服务器读数据时,可以通过从数据库获得数据。

6)使用反向代理和CDN加速网站响应

反响代理和CDN的基本原理就是缓存,目的是尽早返回数据给用户,加快用户访问速度的同时也减轻后端服务器的负债压力。

7)使用分布式文件系统和分布式数据库系统

数据库经过读写分离后,仍然不能满足需求,就需要使用分布式数据库,文件系统也是一样,需要使用分布式文件系统。

分布式数据库是网站数据库拆分的最后手段,只有在单表数据规模非常庞大的时候才使用,不到万不得已,网站更常用的数据库拆分手段是业务分库,将不同业务的数据库部署在不同的物理服务器上。

8)使用NoSQL和搜索引擎

NoSQL和搜索引擎都是源自互联网的技术手段,对可伸缩的分布式特性具有更好的支持。

9)业务拆分

根据产品线划分,将一个网站拆分为许多不同的应用,每个应用独立部署维护。

10)分布式服务

每一个应用系统都需要执行许多相同的业务操作,比如用户管理、商品管理等,那么可以将这些共用的业务提取出来,独立部署。由这些可复用的业务连接数据库,提供共同的业务服务,而应用系统hi需要管理用户界面,通过分布式服务调用共用业务服务完成具体业务操作。

第二章 大型网站架构模式

1.网站架构模式

1)分层

分层是在横向方面进行切分,传统三层:应用层,服务层,数据层。

2)分割

分割是在纵向方面进行切分,将不同业务进行切分。

3)分布式

分层和分割的一个主要目的是为了切分后的模块便于分布式部署,即将不同模块部署在不同的服务器上,通过远程调用协同工作。分布式意味着可以使用更多的计算机完成相同功能。

分布式在解决网站高并发问题的同时也带来其他问题。首先,分布式意味着服务调用必须通过网络,可能会对性能造成严重影响;其次,服务越多,服务器宕机概率越大;另外,数据在分布式环境中很难保持数据一致性;而且分布式开发管理维护困难。

常用分布式方案:

1)分布式应用和服务:将分层和分割后的应用和服务模块分布式部署,可以提高性能和并发行,也可以使不同应用复用共同的服务,便于业务功能扩展。

2)分布式静态资源:网站静态资源如JS,CSS,Logo图片等资源独立分布式部署,并采用独立的域名,即人们常说的动静分离。

3)分布式数据和存储:单台计算机无法提供互联网所需的存储空间,这些数据需要分布式存储。除了对传统的关系数据库进行分布式部署外,为网站应用而生的各种NoSQL产品几乎都是分布式的。

4)分布式计算:搜索引擎的索引构建、数据仓库的数据分析统计等等,都需要庞大的计算。目前普遍采用Hadoop和MapReduce分布式计算框架进行此类批处理计算,将计算程序分发到数据所在的位置以加速计算和分布式计算。

4.集群

使用分布式虽然将分层和分割后的模块独立部署,但是对于访问量达的页面,比如首页,要独立部署成服务器集群化,即多台服务器部署相同应用构建一个集群,通过负载均衡设备共同对外提供服务。服务器集群可以提供更好的并发特性,当有更多用户访问,只需向集群中加入新机器,当某台服务器故障,负载均衡设备会将请求转发到集群中其他服务器上。

5.缓存

缓存就是将数据存放在距离计算最近的位置加快处理速度。缓存无处不在。

1)CDN:即内容分发网络,部署在距离终端用户最近的网络服务器,缓存网站一些静态资源,以最快速度返回给用户。

2)反响代理:反响代理属于网站前端架构的一部分,部署在网站前端,用户请求首先访问的就是反响代理服务器,这里缓存网站的静态资源,无需转发给应用服务器就能返回给用户。

3)本地缓存:应用程序在本机内存中直接访问数据。

4)分布式缓存:将数据缓存在一个专门的分布式缓存集群中,应用程序通过网络通信访问缓存数据。

使用缓存有两个前提:一是数据访问热点不均匀,某些频繁访问的数据应该放缓存;而是数据不会很快过期,否则缓存数据很快失效编程脏数据。

6.异步

在单一服务器内部可通过多线程共享内存队列的方式实现异步,处在业务操作前面的线程将输出写入到队列,后面的线程从队列中读取数据进行处理;在分布式系统中,多个服务器集群通过分布式详细队列实现异步,分布式消息队列可以看作内存队列的分布式部署。

异步架构是典型的生产者消费者模式。

异步消息队列还有如下特性:

1)提高系统可用性。消费者服务器故障,生产者服务器可以继续在消息服务器中堆积数据,系统整体无障碍;消费者服务器恢复正常后,继续处理消息队列数据。

2)系统解耦。

3)加快网站相应速度。处在业务处理前端的生产者服务器在处理完业务请求后,将数据写入消息队列,不需要等待消费者服务器处理就可以返回,响应延迟减少。

4)消除并发访问高峰(削峰)。网站并发访问突然增大,造成网站负载过重,使用消息队列将突然增加的访问请求数据放入消息队列中,等待消费者服务器依次处理,就不会对整个网站负载造成太大压力。

7.冗余

数据库冗余备份。

8.自动化

目前自动化架构设计主要集中在发布运维方面。比如自动化监控(心跳检测,监控关键数据指标),自动化报警,自动化失效转移,将失效的服务器从集群中隔离出去,自动化降级,通过拒绝部分请求或者关闭部分不重要服务将系统负载降至一个安全的水平。

9.安全

第三章 大型网站核心架构要素

1.性能

在浏览器端,可以通过浏览器缓存、页面压缩、合理布局页面,减少cookie传输等手段改善性能。

使用CDN,将网站静态内容分发至离用户最近的网络服务商机房,使用户通过最短访问路径获取数据。可以在网站机房部署反响代理服务器,缓存热点文件,加快请求响应速度。

在应用服务器端,可以使用本地缓存和分布式缓存。

通过异步操作将用户请求发送至消息队列等待后续任务处理,而当前请求直接返回响应给用户。

如果有高并发请求,用多台服务器组成集群,提高整体处理能力。

在代码层面,可以通过多线程、改善内存管理等手段优化性能。

在数据库服务器端,索引,缓存,SQL优化等手段很成熟。而NoSQL数据库更加是适合互联网。

2.可用性

网站高可用性的很重要手段是冗余,应用部署在多态服务器上同时提供访问,数据存储在多台服务器上互相备份,任何一台服务器宕机都不影响整体。

对于应用服务器而言,多台应用服务器通过负载均衡设备组成一个集群,任何一台服务器宕机,只需要把请求切换到其他服务器,但是前提条件是不能应用服务器不能保存请求的会话信息,否则转移到其他服务器上无法完成处理。

对于存储服务器,需要对数据进行实时备份,当服务器宕机需要将数据访问转移到可用服务器上,并进行数据恢复以保证继续有服务器宕机的时候数据仍然可用。

衡量一个系统架构设计是否达到高可用的目标,就是假设系统中任何一台或者多台服务器宕机,以及出现各种不可预期的问题时,系统整体依然可用。

3.伸缩性

伸缩性是指通过不断向集群中加入服务器的手段来缓解不断上升的用户并发访问压力和不断增长的数据存储需求。

对于应用服务器集群,只要服务器上不保存数据,所有服务都是对等的,通过负载均衡就可用向集群中不断加入服务器。

对于缓存服务器集群,加入新的服务器可能会导致缓存路由失效,进而导致集群中大部分缓存数据都无法访问。虽然缓存数据可用从数据库重新加载,但是应用程序如果严重依赖缓存,整个网站将崩溃。需要改进缓存路由算法保证缓存数据的可访问性。

关系数据库虽然支持数据复制,主从热备等机制,但是很难做到大规模集群的可伸缩性,因此关系数据库的集群伸缩方案必须在数据库之外实现,通过路由分区等手段将部署有多个数据库的服务器组成一个集群。

NoSQL数据库产品,由于其先天就是为海量数据而生的,因此其对伸缩性的支持都很好,可用做到在较少运维参与的情况下实现集群规模的线性伸缩。

4.扩展性

网站快速发展,功能不断扩展,如何设计网站的架构使其能快速响应需求变换,是网站可扩展架构的主要目的。

网站可扩展架构的主要手段是事件驱动架构和分布式服务。

事件驱动架构在网站通常利用消息队列实现,用消息队列对系统进行解耦,系统间耦合少了,才更加好扩展。

分布式服务则是将业务和可复用服务分离开,通过分布式服务框架调用。新增产品可以通过调用可复用的服务实现自身的业务逻辑,而对现有产品没有任何影响。可复用服务升级变更的时候,也可以通过提供多版本服务对应用实现透明升级,不需要强制应用同步变更。

5.安全性

 

第四章 瞬时响应:网站的高性能架构

1.Web前端优化

2.应用服务器性能优化

1)分布式缓存

网站性能优化第一定律:优先考虑使用缓存来优化性能。

a.缓存本质上是一个内存Hash表,网站应用中,数据缓存以一对Key,Value的形式存储在内存Hash表中。缓存主要用来存放读写比很高,很少变化的数据,如商品的类目信息,热门词的搜索列表信息,热门商品信息等。

b.合理使用缓存

  • 频繁修改的数据:如果缓存中保存的是频繁修改的数据,就会出现数据写入缓存后,还没有被使用,就已经失效成为了脏数据,一般来说,数据的读写比在2:1以上,写入一次缓存,被读取两次,这样才有意义。
  • 没有热点的访问:缓存中只保存小部分高访问的数据。
  • 数据不一致与脏读:一般会对缓存的数据设置失效时间,超过时间就要重新从数据库加载。因此应用要容忍一定时间的不一致性,如卖家已经编辑了商品属性,但要等一段时间才能被买家看到。在互联网应用中,是可以被接收的。也可以在数据更新时立即更新缓存,但是要带来更多系统开销和事务一致性问题。
  • 缓存可用性:现在的互联网大量使用缓存,一旦缓存服务崩溃,数据库不能承受这么大压力而宕机。这种情况叫缓存雪崩。可以通过分布式缓存服务器集群,将缓存数据分布到集群多台服务器上,当一台缓存服务器宕机,只有部分缓存数据丢失,从数据库重新加载这部分数据不会对数据库产生很大影响。
  • 缓存预热:缓存中存放的是热点数据,热点数据又是缓存系统利用LRU(最近最久未用算法)对不断访问的数据筛选淘汰出来的。这个过程需要花费较长时间,所以可以在启动加载数据库中数据到缓存进行预热。
  • 缓存穿透:不恰当的数据或者恶意攻击持续高并发的请求某个不存在的数据,由于缓存没有保存该数据,所以会直接请求数据库,一个简单的对策是将不存在的数据也缓存起来(其value值为null),或者用布隆筛选器。

2)异步操作

使用消息队列将调用异步化,可改善网站的扩展性,事实上,使用消息队列还可改善网站系统的性能。

在不使用消息队列的情况下,用户将数据直接写入数据库,在高并发时,对数据库造成巨大压力,使用消息队列后,用户请求的数据发送给消息队列后立即返回,数据由消费者进程写入数据库,由于消息队列服务器处理速度远快于数据库,因此用户的响应延迟可以到有效改善,而且消息队列还可以削峰,减少高并发对系统的冲击。

3)使用集群

多台服务器对抗高并发。

4)代码优化

a.多线程

b.资源复用

系统运行时,要尽量减少那些开销大的系统资源的创建和销毁,比如数据库连接、网络通信连接、线程、复杂对象等。资源复用主要由两种模式:单例(Singleton)和对象池(Object Pool)。

频繁的创建和关闭数据库连接,既耗资源又耗时间,应用程序的数据库连接基本都使用连接池的方式,数据库连接对象创建好以后,将连接对象放入对象池容器中,应用程序要连接的时候,就i从对象池获取一个空闲的连接使用,使用完毕后又归还到对象池中,不需要创建新连接。对于Web请求,Web应用服务器都要创建一个独立的线程去处理,应用服务器采取线程池方式(Thread Pool)。

c.数据结构

d.垃圾回收

 

第五章 万无一失:网站的高可用架构

1.高可用的网站架构

三层架构,应用层、服务层、数据层

应用层通过负载均衡来组成集群,当负载均衡设备通过心跳检测监控到某台应用服务器不可用,就将其从集群列表中剔除,并将请求分发到集群中其他可用的服务器上,整个集群保持可用,从而实现应用高可用。

服务层也是通过集群,和应用层服务器类似,只是这些服务器被应用层通过分布式服务调用框架访问。

数据层服务器在数据写入时进行数据同步复制,将数据写入多台服务器上,实现数据冗余备份。当数据库服务器宕机时,应用程序将访问切换到有备份数据的服务器上。

2.高可用的应用

应用的一个显著特点是应用的无状态性。

无状态的应用是指应用服务器不保存业务的上下文信息,而仅根据每次请求提交的数据进行相应的业务逻辑处理,多个服务器实例(服务器)之间完全对等,请求提交到任何服务器,处理结果都是一致的。

1)通过负载均衡进行无状态服务的失效转移

负载均衡设备通过心跳检测监控到某台服务器不可用,将其剔除,把请求发送到其他服务器上。

2)应用服务器集群的Session管理

目前最好的方式是Session服务器,利用独立部署的Session服务器(集群)统一管理Session,应用服务器每次读写Session时,都访问Session服务器。

这种解决方案事实上是将应用服务器的状态分离,分为无状态的应用服务器和有状态的Session服务器,然后针对这两种服务器的不同特性分别设计其架构。

3.高可用的服务

1)分级管理

显然支付功能比评价功能重要,付费用户比免费用户重要。

2)超时设置

一旦超时,应用程序可选择继续重试或者将请求转移到提供相同服务的其他服务器上。

3)异步调用

用消息队列实现

4)服务降级

在网站访问高峰期,为了保证核心应用和功能正常运行,需要对服务进行降级。降级有两种手段:拒绝服务及关闭服务。

  • 拒绝服务:拒绝低优先级应用,减少服务调用并发数,保证核心应用。或者随机拒绝部分请求调用,节约资源让一部分请求成功,避免要死大家一起死。
  • 关闭功能:关闭部分不重要功能,淘宝在双11时,关闭“评价”,“确认收货”等非核心功能。

5)幂等性设计

服务重复调用是无法避免的,可能服务处理成功了,但是网络原因未收到响应,就被当作调用失败从而重试服务调用(如果是转账业务就麻烦了)。因此必须在服务层保证服务重复调用和调用一次产生的结果相同,即服务具有幂等性。

4.高可用的数据

保证数据存储高可用的手段主要是数据备份和失效转移机制。数据备份是保证数据有多个副本,任意副本丢失都不会导致数据的永久丢失。而失效转移机制则保证当一个数据副本不可访问时,可用快速切换访问数据的其他副本,保证系统可用。

1)CAP原理

为了保证数据的高可用,网站通常会牺牲另一个也很重要的指标:数据一致性。通常会选择强化分布式存储系统的可用性和伸缩性,而在某种程度上放弃一致性。

数据一致性又可分为以下几点:

  • 数据强一致性:各个副本的数据在物理存储中总是一致的。
  • 数据用户一致:数据在物理存储中的各个副本的数据可能是不一致的,但是终端用户访问时,通过纠错和校验机制,可用确定一个一致的且正确的数据返回给用户。
  • 数据最终一致性:物理存储数据可以不一致,用户访问到的数据可以不一致,但系统经过一段时间的自我恢复和修正,数据最终达到一致。

2)数据备份

a.冷备,定期将数据复制到存储介质中。

b.热备,实时备份,又分为异步热备和同步热备。

异步热备:存储服务器分为主存储服务器(Master)和从存储服务器(Slave),正常情况下只备份到主存储服务器,异步线程把数据备份到从存储服务器。

同步热备:存储服务器没有主从之分,完全对等,多份数据副本写入操作同步完成,所有存储服务器还会返回操作成功的响应。

关系数据库热备机制就是Master-Slave同步机制。实践中,通常使用读写分离的方法访问Master和Slave数据库,写操作只访问Master数据库,读操作只访问Slave数据库。

3)失效转移

a.失效确认:确认一台服务器是否宕机的手段有两种,心跳检测和应用程序访问失败报告。

b.访问转移:确认某台数据存储服务器宕机后,就需要将数据读写访问重新路由到其他服务器上,当然,两台服务器是完全对等存储的服务器。

c.数据恢复:从健康的服务器复制数据。

5.高可用网站的软件质量保证

1)网站发布

网站发布过程事实上和服务器宕机效果相当,发布过程中,每次关闭的服务器都是集群中的一小部分,并在发布后立即可以访问,整个发布不影响用户使用。

2)自动化测试

3)预发布验证

即使经过严格测试,发布到正式环境还是会出现问题,所以先发布到预发布服务器上。

预发布服务器是一种特殊用途的服务器,它和正式服务器都部署在相同的物理环境,它和正式服务器唯一不同就是没有配置在负载均衡服务器上,外部用户无法访问,如果预发布服务器上执行的测试验证是正确的,基本上可以保证正式服务器部署时也是没有问题的。

4)代码控制

用源代码工具进行管理。

5)自动化发布

火车发布模型。

6)灰度发布

应用发布成功后,如果软件发生故障,就需要做发布回滚,恢复到上一个版本。但是如果是大型网站,进行发布回滚,那么也很耗费时间。

灰度发布将集群服务器分为若干部分,每天只发布一部分服务器,运行稳定没有故障,第二天继续发布一部分服务器,持续几天全部发布完毕,期间如果发现问题,只需要回滚已发布的一部分服务器即可。

6.网站运行监控

1)监控数据采集

a.用户行为日志收集

  • 服务器端日志收集
  • 客户端日志收集:利用页面嵌入Javascript脚本收集用户信息。

b.服务器性能监控

包括内存,CPU,磁盘,网络等。

c.运行数据报告

缓冲命中率,平均响应延迟时间,每分钟发送邮件数目、代处理的任务总数等。

2)监控管理

  • 系统报警:邮件、短信
  • 失效转移
  • 自动优雅降级

第六章 永无止境:网站的伸缩性架构

所谓网站的伸缩性是指不需要改变网站的软硬件设计,仅仅通过改变部署的服务器数量就可以扩大或者缩小网站的服务处理能力。

使用服务器集群,通过不断的向集群中添加服务器来增强整个集群的处理能力,这就是网站系统的伸缩性架构,网站架构发展史就是一部不断向网站添加服务器的历史。

1.网站架构的伸缩性设计

1)不同功能进行物理分离实现伸缩

网站早期是通过增加服务器提高网站处理能力,新增服务器总是从现有服务器中分离出部分功能和服务。分离又分为纵向分离和横向分离。

  • 纵向分离:分离出三层架构
  • 横向分离:将不同的业务模块分离出来,对单一功能进行分开部署。

2)单一功能通过集群规模实现伸缩

随着网站访问量的增加,就算分离到最小粒度,单一的服务器还是不能满足业务规模,所以要将相同服务部署到多台服务器上构成一个集群对外提供服务。

当一头牛拉不动车的时候,不要去寻找一头更强壮的牛,而是用两头牛来拉车。

集群伸缩性又可分为应用服务器集群伸缩性和数据服务器集群伸缩性。

2.应用服务器集群的伸缩性设计

负载均衡算法:

  • 轮询:所有请求被依次分发到每台应用服务器上,即每台服务器需要处理的请求数目都相同,适合于所有服务器硬件都相同的场景。
  • 加权轮询:按照配置的加权把请求分配到服务器上,高性能的服务器分配到更多请求。
  • 随机
  • 最少连接:记录每个应用服务器正在处理的连接数,新到的请求发送到最少连接的服务器上。
  • 源地址散列:根据请求来源的IP地址进行Hash计算,得到应用服务器,这样来自同一个IP地址的请求总在同一个服务器上处理。

3.分布式缓存集群的伸缩性设计

分布式缓存集群的伸缩性不能使用简单的负载均衡手段来实现,因为分布式缓存服务器集群中不同服务器中缓存的数据各不相同,缓存访问请求不可以在缓存服务器集群中任意一台处理,必须先找到缓存有需要数据的服务器,然后才能访问。

新上线的缓存服务器没有缓存任何数据,而已下线的缓存服务器还缓存网站许多热点数据,所以必须让新上线的缓存服务器对整个分布式缓存集群影响最小,也就是新加入缓存服务器后应使整个缓存服务器集群中已经缓存的数据尽可能还没访问到,这就是分布式缓存集群伸缩性设计的最主要目标。

算法见原书。

4.数据存储服务器集群的伸缩性设计

数据比缓存可靠性要高,所以设计更加复杂。

1)关系数据库集群的伸缩性设计

  • 主流关系数据库都支持数据复制功能,数据写入到主数据服务器,主数据服务器将数据复制到许多从数据服务器上。这样一来,主数据服务器用来写,从服务器用来读,从而达到读写分离的目标。
  • 不同业务数据表部署在不同的数据库集群上,即数据分库,但跨库的表不能Join操作。

2)NoSQL数据库的伸缩性设计

 

第七章 随需应变:网站的可扩展架构

1.构建可扩展的网站架构

设计网站可扩展的核心思想是模块化,并降低模块间的耦合,提高模块的复用性。

网站通过分层和分割的方式进行架构伸缩,分层和分割也是模块化设计的重要手段,它们将软件分割成若干个低耦合的独立模块,按照模块进行部署,模块分布式部署以后具体聚合方式主要有分布式消息队列和分布式服务。

2.利用分布式消息队列降低系统耦合性

1)事件驱动架构

事件驱动架构(Event Driven Architecutre):通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作。典型的EDA架构就是操作系统中常见的生产者消费者模式,具体实现手段也很多,比如分布式消息队列。

2)分布式消息队列

为了避免消息队列服务器宕机造成消息丢失,会将消息成功发送到消息队列的消息存储在消息生产者服务器,等消息真正被消费者处理器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中其他的服务器发布消息。

3.利用分布式服务打造可复用的业务平台

随着网站功能越来越多,网站应用系统会成为一个巨无霸,给开发,维护,部署都带来了巨大麻烦。

  • 编译、部署困难
  • 代码分支管理困难
  • 数据库连接耗尽
  • 新增业务困难

解决方案就是拆分,将模块独立部署,降低耦合。拆分分为纵向拆分和横向拆分。

  • 纵向拆分:将一个大应用拆分成多个小应用,如果新增业务比较独立,那么直接设计部署成一个独立的Web应用程序。
  • 横向拆分:将复用的业务拆分出来,独立部署为分布式服务,新增业务只需要调用这些分布式服务,不需要依赖具体的模块代码,即可快速搭建一个应用程序,而模块内业务逻辑变化时,只要接口保持一致就不影响业务程序和其他模块。

1)大型网站分布式服务的需求和特点

分布式服务框架需要支持如下特性:

  • 负载均衡
  • 失效转移
  • 高效的远程通信
  • 整合异构系统:网站服务可能会使用不同语言开发并部署到不同的平台,分布式服务框架需要整合这些异构的系统。
  • 对应用最少侵入
  • 版本管理
  • 实时监控

2)分布式服务框架设计

Dubbo

4.利用开放平台建设网站生态圈

大型网站为了更好的服务自己的用户,开发更多的增值服务,会把网站内部的服务封装成一些调用接口开放出去,供外部的第三方开发者使用,这个提供开发接口的平台被称为开放平台。第三方开发者利用这些开放的接口开发应用程序(APP)或者网站,为更多的用户提供价值。网站、用户、第三方开发者相互依赖,形成一个网站的生态圈,既为用户提供更多价值,也提高了网站和第三方开发者的竞争能力和盈利能力。目前百度,淘宝,腾讯都建设了自己的开放平台,利用自己庞大用户群吸引第三方开发者,打造一个更加庞大的航母战斗群,在市场竞争中立于不败之地。

 

 

 

 

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值