Jenkins简介与应用

image-20220411181340139

目录

1、Jenkins简介

1.Jenkins简介

image-20220411181418381

jenkins 概述:是一个开源软件项目,是基于 Java 开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。

对于持续集成工具现在也有很多,目前应用最多的是Jenkins

  • Jenkins前身是Hudson,使用java语言开发的自动化发布工具。

  • Jenkins是跨平台的可以在Win、Linux、MacOS部署。

  • Jenkins是应用最广的开源免费的持续集成服务器,企业中普遍使用Jenkins来作为项目集成发布工具

  • Jenkins官方提供的插件使Jenkins更为强大

目前发展超过17年,比较成熟的CI工具(也可以CD)能够实现自动化集成发布。目前普遍使用Jenkins完成持续集成CI/持续部署CD等相关技术实践。 可以把Jenkins想象成一个脚本执行器,我们可以通过编写代码的方式灵活的控制Jenkins作业的运行与控制。

⚠️ 注意:插件是jenkins的一大优势,也是其一大弊端。

1.推荐按需使用。尽量少装一些插件。为什么呢?当以后jenkins越来越大,任务越来越多时,如果插件很多,可能在重启jenkins后会因一些插件问题而导致jenkins无法启动。
2.能不用插件实现的尽量不要使用插件!可以写一些代码来实现,这样可以减少插件的依赖。另外一点,对你的技能提升也是有很大的帮助。

🍀 jenkins官网:https://jenkins.io/

image-20220411184657793

🍀 jenkins发布周期(每周发布一次)

image-20210428060510962

2.Jenkins应用场景

image-20220411182912017

  • 持续集成实践

    • 集成svn/git客户端实现源代码下载检出
    • 集成maven/ant/gradle/npm构建工具实现源码编译打包单元测试
    • 集成sonarqube对源代码进行质量检查(坏味道、复杂度、新增bug等)
  • 持续部署实践

    • 集成SaltStack/Ansible实现自动化部署发布

      ⚠️ jenkins本身没有发布能力,它只是集成了这些工具的特性来实现发布,jenkins只是来调度的。

  • 自动化测试实践

    • 集成Jmeter(压力测试、接口测试)/Soar(小米开源的一个sql扫描)/Kubernetes/

      sonarqube也能支持sql扫描,但是需要付费;

3.Jenkins功能特点

image-20220411184259471

  • 开源免费
  • 多平台支持(windows/linux/macos)
  • 主从分布式架构
  • 提供web可视化配置管理页面
  • 安装配置简单
  • 插件资源丰富

🍀 主从分布式架构:

jenkins:
	master:做调度的。//1个master可以对应若干个agent。
	agent:运行实际任务的。

⚠️ master本身也具有作业构建的能力,但是一般我们用master节点作为调度。master节点不做构建,它只是用来存储这些任务。真正构建的时候,我们在agent上构建。我们做测试的时候,可能会用master节点来做一些任务。但是实际生产环境中,我们绝对不能用master节点去构建任务。因为任务一旦多了,会影响jenkins性能,导致你直接宕机了。

2、Jenkins使用

1.jenkins数据目录

image-20220414170407227

🍀 课件内容

image-20220414170425811

🍀 自己测试过程

  • 注意:jenkins_home
jenkins把所有的数据都存放在了文件系统里面。

rpm方式安装的jenkins: 其家目录在/var/lib/jenkins 目录下;
docker方式安装的jenkins: 其家目录在/var/jenkins_home 目录下;

jenkins所有的配置文件都是以.xml格式存储的!

image-20220414204739831

image-20220414204756768

image-20220417123901671

image-20220414205315986

  • userContent :类似于web站点目录,可以上传一些文件

这里可以放一个index.html文件,然后它会给你展示出来!

类似于sftp功能,用的不是很多!

  • workspace :默认的工作目录

⚠️ 注意:一般要把这个工作目录和jenkins的数据目录要分开存放,要不万一你这个目录io比较高的话,也会对jenkins有影响!

这个目录非常重要,就是我们以后运行的每一个流水线作业,它是在哪里工作,是在这个workspace目录下工作的!

默认情况下,这个workspace目录也是在jenkins_home下,但是我们可以自定义!

2.Jenkins用户管理和权限管理

🍀 课件内容

image-20220414170517411

image-20220414170843488

image-20220414220455155

💧 自己测试过程

⚠️ 注意

就是后面我们把jenkins落地到了企业后,同志们如何登录这个系统呢?我们需要给它创建用户和账号,企业里面用户那么多,我们怎么给他们一一分配账号呢?
1、这里面有一种方法,叫做认证集成,你可以和LDAP系统做对接,LDAP是我们做统一认证的地方,用户的组织结构信息都在这里!
然后我们可以拿LDAP的插件和jenkins做集成,最终实现的一个效果就是,可以用LDAP里面的账号和密码去去登录Jenkins。

2、如果你的集团里面可能没有LDAP,但是你有gitlab,那么Jenkins也可以支持gitlab的单点登录!

所以,登录这一块,一个是它自己的数据库,刚才我们看到的那个jenkins_home目录就是它的数据库。另外一个就是跟认证系统做集成,或者和其他第三方平台做一个sso(类似于单点登录一样!)

我们再刚开始安装的时候创建了一个admin账户,现在我们再创建一个账户xyy

点击系统管理-管理用户

image-20220414220842898

点击新建用户,创建新用户:账号:xyy 密码:123456

image-20220414220934658

查看创建好的xyy账户:

image-20220414220952675

然后退出当前用户,使用刚创建的xyy账户登录jenkins系统:

image-20220414221234295

image-20220414221258988

image-20220414221311898

我们会发现,本来自己是想创建一个普通用户来着的,结果创建的用户具有管理员权限,这可不得了。为什么会这样呢?

我们退出当前账户继续以admin账户登录jenkins:

点击系统管理-安全-全局安全设置:会发现当前授权策略是登录用户可以做任何事,原来产生上面那个现象的原因在这里!😂

image-20220414221505788

image-20220414221538422

🍀 要想解决以上问题,是需要安装一个叫Role-Base strategy的授权插件来着的:

现在,我们来开始安装一下这个插件:

⚠️ 好用的插件也就这个了。这个插件不光提供了ui界面,还提供了api。
很早之前,老师分享了一篇这个Role-Base strategyapi操作的文章,因为老师当时在后台给他们勾选权限的时候,都是框框……,看的眼睛真的受不了了!这个时候就可以调用api去加权限,特别恐怖,勾选一个权限,特别考验你的眼力!(当时老师应该有个公开课来着的)并且其api也没怎么变化!

还有其他同学使用矩阵matrix strategy插件:(这个Role-Base strategy要比矩阵插件好用一些!)

image-20220415082429981

点击系统管理-插件管理

image-20220415083018420

点击可选插件,搜索role,勾选Role-based Authorization Strategy插件,点击现在下载和重启后安装

image-20220415083127522

下载完成后,点击安装完成后重启jenkins

image-20220415083317942

image-20220415083331166

  • 重启完成后,我们还需要开启下Role-based Authorization Strategy:

点击系统管理-全局安全配置

image-20220415083558002

勾选Role-based Strategy,点击应用-保存

image-20220415083642274

  • 开启Role-based Strategy后,我们就可以在首页看到Manage and Assign Roles选项了:

image-20220415083811918

image-20220415083938019

  • 现在是如何配置这个Role-based Authorization Strategy

image-20220415083811918

image-20220415083938019

🍀 我们先看管理角色

image-20220415084201515

image-20220415084329665

Node roles:我们基本上不怎么用到!

image-20220415084405464

Item roles:(项目角色)Item就是每个作业,jenkins里面的每个任务!你可以设置每个组只能构建自己组的作业,但不能构建其他组的作业!

image-20220415084412423

Global roles:全局角色

image-20220415084633464

  • 我们来添加一个组的全局角色:

image-20220415084806048

⚠️ 一般情况,我们是不会让他们去配置任务的,因为一般情况,任务会有专门的人来配置!如果大家都去改,可能这个版本话就不太好了!不能随便去改,否则不可控了!

image-20220415085913308

为了方便,我们再创建一个更高级权限的角色:

t1-devopste-devops-edit

image-20220415085735302

点击应用-保存

image-20220415085846280

  • 配置完成后,我们再次以xyy用户登录jenkins,查看效果:

image-20220415094304964

之前我们遇到过这种情况,用户登录上来后是这个现象,就会联系我们去给他们授权一下。但之前我们是按gitlab的组为单位,gitlab里面有group的概念,group里面有member,这个memer下面其实所有人都属于一个组。所以可以按照这个组为单位,在jenkins里面给他们创建权限!

  • 再次以admin用户登录

我们先来创建一个任务:t1-devops-service,点击创建任务

image-20220415094706242

输入任务名称,选择构建一个自由风格的软件项目

image-20220415094812652

这里先不做任何配置,直接点击应用-保存即可:

image-20220415095004411

按上述方法,我们再创建一个作业t1-devops-ui:(这里可以基于之前已经存在的作业来创建job

image-20220415095219593

image-20220415095236673

image-20220415095326325

两个作业,一个前端,一个后端。

同上,我们再来创建2个作业:

image-20220415095458491

image-20220415095528413

image-20220415095543446

  • 现在我想实现的效果是,例如说xyy是属于t1这个团队的,那么t1团队的用户登录jenkins只能看到t1组的项目,t2团队的用户登录jenkins只能看到t2组的项目,次时该如何配置呢?

我们先需要创建下项目角色:

image-20220415095944367

点击Manage Roles

image-20220415095956849

  • 这里配置下项目权限:

t1-.*?

image-20220415100057189

配置完,点击应用-保存

  • 配置完后,我们这里来给xyy用户授权下:

image-20220415100411487

全局角色:将xyy添加到t1devops组

image-20220415100549512

项目角色:将xyy添加到t1组

image-20220415100654044

配置完成后,点击应用,保存:

image-20220415100713835

  • 以上配置完成后,这里再使用xyy用户登录:

image-20220415125906579

我们会发现,这里怎么也能看到t2组的job呢?

⚠️

这里,我要和大家强调下,全局权限肯定是要大于你的项目权限的!

再次用admin登录,然后配置下全局角色,将任务里的权限全部去掉,然后给项目权限加上任务的Read,Workspace权限

image-20220415130421589

保存配置后,我们再次以xyy用户登录观察现象:

image-20220415130539392

符合预期效果!

🍀 现在我们说下作业管理这一块!

1.根据视图来分类

2.根据文件夹来分类

如果作业很多的话,这里的视图就会看起来特别乱。

image-20220415130933147

1️⃣ 首先我们根据视图来分类

新建2个视图,t1t2

image-20220415131129786

image-20220415131152296

注意:这里可以手动选择添加作业,但如果作业很多的话,我么可以使用正则表达式来处理

image-20220415131314965

同上,添加t2视图:

image-20220415131527796

image-20220415131616733

效果如下:

image-20220415131631415

image-20220415131640029

image-20220415131647938

2️⃣ 我们使用文件夹来管理作业

我们先装下pipline插件

image-20220415131458807

image-20220415131838402

pipeline插件:

image-20220415132018592

等待插件下载完成后,重启jenkins。

我们来新建一个文件夹:

image-20220415132804693

image-20220415132845693

image-20220415132906720

同样,我们可以把作业移动到文件夹里去:

image-20220415132957689

image-20220415133013724

但是此时发现,有些怪怪的:。。。😥

image-20220415145444161

image-20220415145504107

image-20220415142621908

⚠️注意:这里有些问题,需要修改下文件夹名称!

image-20220415143623706

修改完成后,此时一切都正常了:符合预期效果!

image-20220415144640057

image-20220415144648537

image-20220415144656768

image-20220415144727526

🍀 总结

没有基于视图进行授权的,总之,还是要把作业的前缀给命名好!!

🍀 问题:

经验证,是可以看到的,但一般不会这么操作,除非有一些公有项目,一些组建的额依赖!

image-20220415150252606

image-20220415150517263

image-20220415150547651

3.Jenkins项目类型与参数

image-20220414170530314

🍀 之前使用自由风格项目类型,后面全部都换成了pipeline!

这里我们分别创建2个作业,一个是自由风格,一个是流水线:

1️⃣ 自由风格

image-20220415150954695

image-20220415151025132

image-20220415151032738

2️⃣ 流水线

image-20220415150954695

image-20220415151135808

image-20220415151142154

也就是说,pipeline把所有的步骤给你以代码的形式来描述了。

image-20220415151329536

而自由风格这里,都是把这些步骤在图形界面去配置的:

image-20220415151459498

但自由风格入门可能简单一点,这些配置我们都可以在这里选择,基本上,这一条流水线就调好了。

image-20220415151732956

(1)字符参数

image-20220414170602437

🍀 自己测试过程

选择参数化构建过程-字符参数:

image-20220415154915473

填写相应选项:

image-20220415155235280

点击build with parameters

image-20220415155328839

输入版本号信息:

image-20220415155353154

这个是传递给jenkins的参数,那么 jenkins如何去读这个参数呢?

image-20220415155627665

来到流水线选项,修改脚本,引用变量:

image-20220415155738215

再次编译,查看效果:

image-20220415155755906

本次输入1.1.8版本:

image-20220415155810424

查看构建结果:

image-20220415155858476

点击console output

image-20220415155914511

image-20220415155948148

这是我们传递进去的变量,就是这样去引用的!

(2)选项参数

image-20220414170622019

选项参数和字符参数是我们用的最多的!

🍀 自己测试过程

开始配置选项参数

image-20220415160620767

image-20220415160649861

image-20220415160752524

流水线里引用选项参数:

image-20220415160932830

开始构建:

image-20220415161008639

能够看到这里是可以选择envName的:

image-20220415161026491

查看构建结果:

image-20220415161048775

结束。😋

(3)历史构建

image-20220414170647771

🍀 自己测试过程

配置历史构建选项:

image-20220415161648935

image-20220415161714897

进行多次构建并查看效果:发现这边只有最近的5次构建记录

image-20220415161754218

结束。😋

(4)并行构建

image-20220414170701393

🍀 默认就是开启并行构建的(只是一个选项配置而已)

image-20220415162023379

image-20220415162038415

(5)构建触发器

后面离不开api,不管你是运维还是开发,你后面都离不开api了。

这个url你就可以理解为是一个api接口,我们通过给这个api接口去传参,

也可以用postman去测试,专业的测试工具!

选项参数的值是不能改的!

🍀 课件内容

image-20220414170715712

🍀 自己测试过程

image-20220415162544472

image-20220415162606552

scm:源代码管理系统
会定义轮询git版本控制系统的;

关闭构建:不构建

静默期:冷静期,休眠时间

🍀 来演示下这个触发远程构建

image-20220415162645616

开始配置:

image-20220415164210425

image-20220415164306523

JENKINS_URL/job/t2-demo/build?token=TOKEN_NAME 或者 /buildWithParameters?token=TOKEN_NAME

http://172.29.9.101:8080/job/t2-demo/build?token=devops123

http://172.29.9.101:8080/job/t2-demo/buildWithParameters?token=devops123

此时再新建一个t2-demo2的流水线作业:

image-20220415164517368

image-20220415164547997

image-20220415164618819

现在我们先构建下t2-demo2观察下效果:

http://172.29.9.101:8080/job/t2-demo2/build?token=devops123

curl -uadmin:admin http://172.29.9.101:8080/job/t2-demo2/build?token=devops123

在自己虚机上构建就好:

[root@devops ~]#curl -uadmin:admin http://172.29.9.101:8080/job/t2-demo2/build?token=devops123

再到web界面可以看到构建记录的:

image-20220415164843500

现在我们先构建下t2-demo观察下效果:

http://172.29.9.101:8080/job/t2-demo/buildWithParameters?token=devops123&version=1.1.4&envName=prod

先在web界面看下,目前为第8次构建:

image-20220415180845326

此时在虚机上我们执行远程触发构建:

[root@devops ~]#curl -uadmin:admin  http://172.29.9.101:8080/job/t2-demo/buildWithParameters?token=devops123&version=1.1.4&envName=prod

image-20220415181124737

image-20220415181154796

🍀 特备注意下:这里要使用双引号引起来,不然有问题的。。。。

[root@devops ~]#curl -u admin:admin  "http://172.29.9.101:8080/job/t2-demo/buildWithParameters?token=devops123&version=1.1.4&envName=dev"

image-20220415182716399

这里模拟几次报错:

🍀 缺少认证信息

image-20220415181415310

🍀 访问方式错误

image-20220415181507879

🍀 一定要存在,不存在的也报错!

image-20220415182805259

image-20220415182822944

测试结束。😋

适合做系统之间的集成去使用的。比如说提交代码之后自动触发jenkins去构建,这个触发器也是能完成一些,但是它还是不够灵活。后面会讲更加灵活的方式的。

(6)定时构建

image-20220414170733970

(7)Jenkins视图

image-20220414171130091

4.Jenkins凭据管理

🍀 课件内容

image-20220414170910334

image-20220414171109175

🍀 自己测试过程

凭据管理,这个在装pipelin插件就会装好了的。

其实,jenkins的凭据管理不是很安全,但总比明文密码要强很多!

创建凭据:

image-20220415201428647

image-20220415201449920

image-20220415201501489

image-20220415201644300

image-20220415201703318

使用凭据:

图形化界面,其实我们不推荐大家使用了!

image-20220415202106762

image-20220415202130853

image-20220415202246816

以后都是使用流水线pipeline:

image-20220415202340028

image-20220415202534246

image-20220415202607397

后期流水线里,我们就是用这种方式去写,这样的话,它就会把这个凭据对应的账号和密码都赋予给对应的变量,我们就可以像使用环境变量一样去调用username和password。

结束。😋

5.Jenkins BlueOcean

Blue Ocean减少了混乱而且进一步明确了团队中每个成员

Blue Ocean 的主要特性包括:

  • 持续交付(CD)Pipeline的 复杂可视化 ,可以让您快速直观地理解管道状态。
  • Pipeline 编辑器 - 引导用户通过直观的、可视化的过程来创建Pipeline,从而使Pipeline的创建变得平易近人。
  • 个性化 以适应团队中每个成员不同角色的需求。
  • 在需要干预和/或出现问题时 精确定位 。Blue Ocean 展示 Pipeline中需要关注的地方,简化异常处理,提高生产力。
  • 本地集成分支和合并请求, 在与GitHub 和 Bitbucket中的其他人协作编码时实现最大程度的开发人员生产力。

官方文档:https://jenkins.io/zh/doc/book/blueocean/getting-started/

BlueOcean也是需要很多很多的依赖,后来我们就自己开发了devops平台。

🍀 老师课件内容

image-20220414171025303

image-20220414171032182

image-20220414171042326

🍀 自己测试过程

https://github.com/OnlyOnexl/cidevops-java-service

https://github.com/cidevopsci/cidevops-java-service/blob/master/Jenkinsfile

image-20220417155711656

安装BlueOcean插件:

image-20220415203335658

image-20220415203354642

下载外重启jenkins。

进入BlueOcean:

image-20220415203734029

image-20220415211148661

运行

image-20220415211216735

实战测试:(测试成功)-2022.4.16

实验仓库代码:

image-20220415220056877

image-20220415220113581

image-20220415220126039

生成token:

image-20220415220344655

image-20220415220409128

image-20220415220429691

image-20220415220329209

image-20220415220604010

image-20220415220702362

image-20220415220758019

image-20220415220646594

这里直接form一下代码仓库就好:

image-20220415221047560

image-20220415221103682

image-20220415221206686

image-20220415221310509

但是有时构架就会报错:

image-20220415221602764

image-20220415221642621

符合预期效果!😘

注意事项

📍 问题:我这边用docker安装的jenkins,怎么这么卡呢。。。。一直刷新不出来,老师也是用容器起的jenkins,都没问题。。。-2022.4.14

最后通过docker restart jenkins命令重启下jenkins容器就好了。。。。;

image-20220414164009396

📍 重点学习jenkins的思想

我们去学习一个工具,不仅是学它这个技术本身,而是去了解这个技术的设计思想。比如jenkins,这个工具已经有16 17年了,已经很稳定了,但也面临着一个被替换的局面。但实际jenkins背后的这些思想和这个设计,很值得我们去学习。你只要把jenkins后面的思想掌握了之后,后面你再用任何一款ci工具,或者我们市面上见的这些devops平台,你都可以一通百通。

我们通常一般可以用jenkins来完成任何你想自动化的任务。比如你想做一个自动构建打包,自动构建发布。
一句话,你想要做的jenkins都能去帮你实现!
只要能调接口实现的,jenkins都可以去包一层的!

未来:
后面,我们把jenkins做成一个引擎,外面包了一个devops平台,然后devops平台去调jenkins,这样就不用让用户再操作jenkins了。

devops:
我们是一个功能效能团队,提供的技术和支撑,什么时候来发,最终是交给开发,他们自己来发的。
现在有一种模式就是:自己开发的应用自己去维护。

🍀 学习jenkins后,需要学习一些语言的!

你会发现吗,用了jenkins之后,你要学习很多种语言!
gooary,学完这个语言后,你后面写流水钱基本就没什么问题了!
shell,python,go(k8s二开)

🍀 注意:jenkins的最佳实践:我们建议不用它那个web ui页面了,我们直接用它的pipline,就是以代码的方式去描述我们每一条流水线。

🍀 可能有些插件,你装完就是需要重启下jenkins!

🍀 问题:master节点和slave节点可以在一台机器上吗?

是可以的!

🍀 注意:配置完成后,可以直接点击Save的,这样就直接调到上一级页面了!

而点击应用是只保存了配置,但不会返回到上一级页面。

image-20220415130158654

📍 生产里一般使用2套jenkins

开发/测试:1套jenkins
生产环境:另一套jenkins (预发布环境和生产环境基本是一样的)

📍 snoar:代码扫描工具

sonar 代码质量检查:硬编码检查,安全检查,单元测试是否通过,代码质量

snoar:

  • 旧项目:还是算了哈哈。(一扫就扫除很多bug哈哈) 需要有一个宽容的规范,例如对于旧的项目,我们只需要考虑新增代码的质量,然后你再慢慢去改这个旧代码。

  • 新项目:用sonar去扫描,很容易改;一开始,就开发按照这个语言规范去写,基本上就没有什么问题;

📍 问:yarn优化问题

答:yarn相较于npm,它的速度更快一些!-2022.4.10

优化就是:你把这个源放到内网;另外,就看你的机器性能要好一些;

📍 注意:新版本bug

但不影响使用!-2022.4.15

image-20220415132348501

📍 问题:静态节点/动态节点

  • 问题现象

image-20220415195452441

回答:

slave,我们有2种情况。我们再jenkins里面添加节点的时候,它有一个概念叫做固定节点(静态节点),也有一个叫动态节点。

动态节点:可能你按照作业的数量,假如说来了10个作业,那我可能就会临时拉取10个agent来进行构建。那拉取的这个过程,肯定会耗时间的。因为它也是调k8s的api,去给你创建一个pod。

还有一种方法叫做静态pod:静态pod不会随时给你销毁掉,它是一直运行在k8s集群里面的,它一直在连着jenkins的master,来了认为它就去执行。因为部署在了k8s里面,它也具有这个水平扩展能力,动态的弹性也是有的。

所以你要是觉得动态那种方式慢的话,那建议及就改成静态这种方式。

静态的就是有些浪费资源,所以这个要平衡一下。

如果现在用的是jenkins那个插件的话,要考虑到构建时间、资源情况,那就得自己去搞一个这样的平台了,把这个逻辑去实现一下,因为jenkins那个插件还是有点慢的。

关于我

我的博客主旨:我希望每一个人拿着我的博客都可以做出实验现象,先把实验做出来,然后再结合理论知识更深层次去理解技术点,这样学习起来才有乐趣和动力。并且,我的博客内容步骤是很完整的,也分享源码和实验用到的软件,希望能和大家一起共同进步!

各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人免费帮您解决问题:

  1. 个人微信二维码:x2675263825 (舍得), qq:2675263825。

    image-20211002091450217

  2. 个人微信公众号:云原生架构师实战

    image-20211002141739664

  3. 个人博客地址:www.onlyonexl.cn

    image-20211002092057988

  4. 个人csdn

    https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

    image-20211002092344616

  5. 个人已开源干货😘

    资料链接:《不服来怼:宇宙中最好用的云笔记!& 其他开源干货》

    https://www.yuque.com/go/doc/73723298?#

    image-20220417084709077

最后

好了,关于Jenkins简介与应用到精通就到这里了,感谢大家阅读,最后贴上我女神的photo,祝大家生活快乐,每天都过的有意义哦,我们下期见!

image-20220416091448084

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值