【架构设计】系统重构

27 篇文章 2 订阅
订阅专栏

1、前言

1.1 现在所写的每一行代码,都是未来的遗留系统

有些系统虽然刚开发不久,但你工作起来还是有各种不爽,比如:

  • 代码质量一言难尽,改个需求或做维护经常加班,让你恨不得推翻重写;
  • 架构混乱,模块之间职责不明,一个需求需要修改四五个服务;
  • CI/CD 运转不畅,经常莫名其妙地挂掉,每次升级、上线都一拖再拖;
  • 团队结构不稳定,人员变动频繁;大家都在拼命开发新需求,没人关心技术债;

如果以上问题你都自信满满,那我就要拿出杀手锏了。

你的代码有测试吗?你平时开发新需求时会写测试吗?你在修改 bug 时会补测试吗?经过这样的灵魂三问,你还有自信坚持说自己的系统不是遗留系统吗?

《修改代码的艺术》一书的作者 Michael Feathers 说过,“没有测试的代码都是遗留代码”。在我们越来越强调软件系统质量内建的今天,仍然有很多系统甚至很多刚刚开发的新系统,由于各种原因不写测试。有的说工期太紧,没时间写;有的说系统原来就没测试,我新加的这么几行代码没必要写。其实每种借口都禁不起推敲,都是在为自己不会写测试来打马虎眼。

软件系统本身就是一个不断熵增的过程,代码逐渐从有序变得无序。如果没有测试的严防死守,熵增的过程就会慢慢加快,代码很快就会变得混乱不堪。

1.2 为什么要对遗留系统进行现代化

不知道你是否跟曾经的我一样,身处一个遗留系统的漩涡之中,每天为毫无头绪的代码和混乱不堪的架构发愁。一个新的需求来了,都不知道从哪儿开始改起,即便看似简单的需求都要很久才能上线。

我想我们是不是得先明确一下,到底什么样的系统才能称之为遗留系统呢?它存在哪些问题,复杂在哪里?

关于遗留系统的误区

请你先思考这样一个问题:假如一个系统七八年了,它是不是个遗留系统?

系统的时间长等同于就是遗留系统,这是很多人的一个误区。虽然大多数遗留系统确实是存在的时间很长,但并不等于时间长的都是遗留系统。

遗留系统的特点

  • 首先就是代码质量差。我们说优秀的代码都是相似的,而糟糕的代码则各有各的糟糕之处。
    我曾治理过一个有着 6000 行代码的单个方法,至今印象深刻。其中包含 6 个大的 if/else 块,每个块中大概有 1000 行左右的代码,这 6 个 1000 行的代码只有十分细小的差别。显然是开发人员为了偷懒,不敢在原代码上改动,于是复制出来加入自己的逻辑。他倒是图省事儿了,但是对于维护人员来说简直是噩梦。正所谓编码一时爽,维护火葬场。
  • 其次是架构,这也是遗留系统的重灾区。
    一个软件架构的作用,是要解决多个业务模块之间的协作问题。但如果架构混乱,多个模块之间往复调用,数据也是随意访问,模块之间的边界就会变得模糊,数据所有权也会变得含糊。试想一下,如果一张表被 10 个模块访问,谁能说得清这张表到底属于哪个模块呢?

下图是一家银行的核心应用系统模块之间的交互图,我想没有一个人愿意工作在这样的系统上吧?
在这里插入图片描述
综合来看,代码和架构的质量差会导致遗留系统的维护成本相当高昂。这里的维护就包括:新需求的添加、线上 Bug 的修改,以及为了维护系统运行所需投入的软硬件和人力等。

1.3 什么是遗留系统

说了这么多,我们似乎已经有了一个很具体的关于遗留系统的画像了,参考如下:
在这里插入图片描述
那是不是可以进一步抽象一下概念了呢?

在计算机领域,遗留系统是一种使用旧的方法和技术的、过时的,却仍旧在使用的计算机系统。

1.4 遗留系统重构的价值

原因有很多。首先,可能是成本太高了,企业不愿意投入资源去改进;也可能是因为积重难返,根本改不动。而遗留系统往往都是企业的核心业务系统,支撑着整个企业的业务运营,这样的系统就算问题再多,也是不可替代的。

其次,遗留系统蕴含了大量的数据资产。遗留系统中的数据虽然很难与其他系统进行集成,但这部分数据的价值又是巨大的。企业的新系统常常不得不在这些数据的基础之上去构建,其他系统要想获得遗留系统中的数据,就必须对遗留系统进行修改,所以很多团队为了避免修改代码就会去寻求数据库层面的复制和同步,这也是一个选择。

另外,遗留系统中还藏匿着丰富的业务知识。由于业务人员长期使用并且养成了习惯,很多软件系统已经与业务融为一体,很难区分哪些是真正的业务,哪些是系统的设计。而由于系统历时太久,已经失去了能够正确描述系统现状的文档,所以到最后只有遗留系统的代码才能够准确表达系统的行为,以及与之对应的业务知识。

系统改造,有可为有可不为,而对于遗留系统来说,结合其现代化价值,看上去更像是一种不得不为。所谓现代化,其实就是从代码、架构、DevOps 和团队结构这四个方面来对遗留系统进行治理。

既然不能对遗留系统听之任之,我们就要下决心迎难而上,掌握主动权,否则当问题真正出现时就为时已晚了。

2、遗留系统四化建设

那遗留系统现代化的正确方向到底是什么呢?结合上节课的分析,遗留系统在代码、架构、测试、DevOps 方面存在诸多问题,我们在此基础上,将代码和测试合并(因为它们说的都是代码的质量),并引入开发团队这个维度,就得到了遗留系统现代化的四个方向:代码现代化、架构现代化、DevOps 现代化和团队结构现代化。

2.1 代码现代化

代码现代化顾名思义,就是把遗留系统中丑陋的“祖传”代码重构成职责清晰、结构良好的优质代码。

之所以说遗留系统中的代码是“祖传”的,是因为它和其他祖传的东西类似,都是历史悠久、且不敢轻举妄动的。而之所以不敢轻举妄动,就是因为缺乏测试,无法快速验证修改的正确性。而大多数情况下,之所以没有测试,又是因为代码写得不可测。可测试的代码和代码的测试是相互依存的,其中一个做到了,另一个也很容易做到,而如果其中一个没有做到,另一个也必然无法做到。

因此代码现代化的首要任务,就是对遗留系统的代码进行安全的可测试化重构。

在正常情况下,重构应该是在充分的自动化测试的保护下进行的。但对于没有测试的代码,我们只能“硬着头皮”去做一些相对来说比较安全的重构,将代码重构成可以写测试的程度,然后再补上大量的测试,进而在有充分测试覆盖的情况下,进行更广泛更深入的重构。

2.2 架构现代化

遗留系统现代化的第二个方向是架构现代化。看到“架构现代化”这几个字,有些同学很自然地就想到了微服务架构或云原生架构。然而我们前面说过,新不代表正确。在团队的开发能力、DevOps 能力和运维能力不足的时候,引入微服务,反而会将团队推向更痛苦的深渊。

有时候我们常常把软件系统比作一个城市,把系统架构和城市建设做类比。随着城市的发展和扩张,以前处于城市边缘的农村,反而会被周围新建的高楼大厦包裹成为一个城中村。治理这些城中村,就叫“改造老城区”。

有时候老城区的设计和规划会暴露出一些问题,不足以满足城市的发展。比如市政府通过一些集中的招商引资后,很多企业都要来这里建厂,但老城区显然没有足够的空间。这时候很多城市都会新建一个城区,有些地方叫开发区,有些地方干脆直接就叫新区。我们将这称之为“建设新城区”。

同样,遗留系统的架构现代化,我们也可以分成“改造老城区”和“建设新城区”两类模式。

  • 改造老城区模式是指对遗留系统内部的模块进行治理、让模块内部结构合理、模块之间职责清晰的一系列模式。
  • 建设新城区模式是指将遗留系统内部的某个模块拆分到外面,或将新需求实现在遗留系统外部的一系列模式。

2.3 DevOps 现代化

代码和架构现代化了,DevOps 的现代化也不能落后。它对项目的重要性不言而喻,如果没有现代化的 DevOps 平台,代码和架构现代化所带来的优势,就无法淋漓尽致地体现出来。

假如在代码和架构优化后,需求的开发时间缩短了一倍,那么大家对于新需求上线的时间点自然也有新的期待。然而落后的 DevOps 水平反而会让这个时间变得更长,因为单体架构变成微服务了,DevOps 的难度增加了。

DevOps 的历史虽然只有短短十几年,但最近几年的发展势头却很足。大大小小的公司都开始了 DevOps 转型,很多项目都声称自己建立了持续集成流水线,但实际上很多都是只见其形不见其神,只学其表不学其里。

2.4 团队结构现代化

如果说代码、架构和 DevOps 的现代化还好理解的话,那这个团队结构现代化是个什么东西?其实很多时候,一个开发团队的结构是否合理,决定了这个团队的交付效率、产品质量,甚至项目成败,而很多人还没有对此产生足够的重视。

近年来有一本新书,叫做 Team Topologies,中文直译就是团队拓扑。一上市便引起了不小的轰动。它将团队放到了软件开发的第一位,提出了四种团队拓扑结构和三种团队交互模式。四种团队拓扑包括业务流团队、复杂子系统团队、平台团队和赋能团队。三种团队交互模式包括协作、服务和促进。我们在进行开发团队的组织结构规划时,应该参考这四种团队拓扑。去年这本书的中文版——《高效能团队模式》也已经上市了。

我们对于团队结构的现代化,基本上是围绕这本书的内容展开的。因为我发现,遗留系统中团队的问题,有时比遗留系统本身更大。比如很多遗留系统可能只有一两个人在维护,在他们遇到困难的时候根本得不到团队的支持;再比如一些遗留系统的“老人”对系统比较熟悉,因此任何新启动的专项治理小组都会邀请他们加入,导致这些人的变动十分频繁,上下文切换的成本极其高昂。

团队拓扑不仅对遗留系统至关重要,对一个新系统如何组建开发团队、团队之间如何沟通协作也是至关重要的。

3、现代化建设的策略

3.1 现代化建设的五种策略

1、Encapsulate(封装)

第一种策略是 Encapsulate,也就是将遗留系统中的数据或者功能封装成 API,供外部调用

场景一

我们在上面提到过,遗留系统中蕴含着丰富的数据资产,但是因为技术和工具落后,导致它难以与新系统集成,这些数据被封印在遗漏系统中,成了数据孤岛。比如早期的银行或民航软件,很多都是部署在大型机上的。企业非常希望开发手机 App,这样才能更好地为客户服务,但却很难访问到主机上的这些数据。

同样地,遗留系统中还有一些功能十分重要,其他外部系统需要这些能力来构建业务。比如一些公文流转的工作流,可能构建在基于 Lotus Notes 的办公系统中,但如果企业想要开发移动办公 App,并在 App 中复用这套工作流,也是困难重重。

问题虽然棘手,但事到临头,工程师们总要想办法应对。结合刚才说的情况,我们可以封装这些数据和功能,形成 API,供这些移动 App 或其他外部系统使用。如果遗留系统本身就是基于 Web 的,可以在 Web 系统上直接构建 API;如果不是,可以选择构建一个全新的 Web API 来部署并提供服务。

这样做的好处是,以较低的成本和风险,尽可能满足外部系统的需求。你无需对遗留系统做较大的修改,只是增加一些 API 而已。遗留系统本身不会被优化,但它可以通过这些 API 对外提供能力。

场景二

还有一种情况,我也建议你使用封装的策略,那就是当你有一个第三方系统,希望扩展它的功能,但只能访问它的数据库,却无法修改代码的时候。

这时有些团队采用的方式就是直接连它的数据库,并在已有的系统中基于这些数据构建新的功能。我不建议你这么做,直接连数据库固然简单,但由于你可以访问它所有的表和列,距离混乱也就剩一步之遥了。

我建议你基于这个第三方系统的数据库构建一个 Web API,来向其他的系统提供你想提供的数据和功能,而不是暴露全部的数据。

我这里也稍微剧透下,封装的策略落到具体应用的时候,衍生出了很多相关模式,比如数据 API 模式、功能 API 模式等等。

2、Replatform(重播)

第二种策略是 Replatform,也就是替换运行时平台。这种策略不需要对代码大动干戈,只需要改动很小一部分。到了新的平台后,软件的功能和特性仍然保持不变。

比如,很多银行或民航软件还是基于 COBOL 的主机系统,把它们从大型机上迁移到 Linux 或 Windows 环境,就会甩掉昂贵的主机成本。

在使用 Replatform 时,你只需要对代码做少量更改,以适配新的平台。这样,只通过较小的成本就可以降低基础设施的成本,并提高性能。

还有一种迁移我认为也可以看做是 Replatform,虽然它并不是替换运行时平台。那就是迁移代码版本管理工具。比如你把代码从 SVN 迁移到 Git 中,不需要修改任何功能代码,但却可以享受新的代码管理平台带来的好处。

3、Rehost(重新)

第三种策略是 Rehost,也就是将应用程序或组件部署到其他基础设施中,如虚拟主机、容器或云。这种策略完全不需要修改代码,而只需要迁移部署的环境,甚至都不需要重新编译,因此这种迁移方法也有个很形象的别名,叫做“lift and shift”,就是原封不动地拎起来,转移到别的地方去。

Rehost 可以让你在完全不修改已有系统的情况下,快速上云,体验云环境带来的弹性、安全性和高性能,并且迁移过程也能做到很平滑。然而由于没有任何适配,也就无法充分利用云原生的优势,因此还需要对系统内部的代码和架构做进一步调整,比如将单体架构拆分为可以独立运维的微服务。

4、Refactor/Rearchitect(重构)

第四种策略是 Refactor 和 Rearchitect,它们是指在不改变系统外部行为的前提下,对代码或架构进行调整、优化,以偿还拖欠已久的技术债务、改善非功能需求、提升系统健康度。

  • Refactor 主要是指代码级别的重构,比如你可能用 Sonar 等代码扫描工具,扫描出了很多代码坏味道、缺陷或隐患,修复这些问题的过程就属于 Refactor。这和我们平时说的代码重构基本上是一个意思。
  • Rearchitect 是指架构级别的重构,它包含两层意思。
    • 第一层比较好理解,就是指从单体架构到分布式架构的这种架构调整。
    • 第二层是指不改变部署单元之间的关系,而是对单个或多个部署单元内部进行模块化或分层重构。
      由于这种模块化和分层也会涉及很多代码的调整,所以这种 Rearchitect 往往会和 Refactor 同时进行。
5、Rebuild/Replace(替换)

第五种策略是 Rebuild 和 Replace,都是指对遗留系统进行替换。它们两个替换的范围和程度不同。

  • Rebuild 可能是对应用程序的某个组件或某个服务的重新设计或重写,但会保留其原有的业务范围和业务规则。
  • Replace 是指彻底淘汰应用程序的所有组件,去构建或购买新的软件,同时会考虑添加新的业务需求或移除某些旧的业务需求。

下图是对上面五种策略的一个总结,你可以从中看出它们的收益、风险和成本(用面积表示):
在这里插入图片描述
遗留系统现代化的几种策略,不同的策略有不同的适用场景,我把它们总结到了一张表中。
在这里插入图片描述
你要记住的是,一定要根据项目的情况来选择不同的策略组合。不要上来就大张旗鼓地重构或重写,一定要弄清楚想要的是什么。除了重构和重写,你其实还有很多选择。

3.2 成果校验

在这里插入图片描述
有效的成果验证既能鼓舞团队士气,又能让领导和业务方感受到改造的价值,还能为你后续的改造安排打下良好的试点基础和团队实力。

遗留系统现代化长路漫漫,千万不要因为这些比较容易做却没有做的小事儿,而半途而废啊。

系列文章|云原生时代下微服务架构进阶之路 - 微服务拆分的最佳实践
VMware中国研发中心
07-15 300
通过本篇文章您可以了解到以下内容: · Monolithic 到 Microservices 的思考(回顾) · 应用现代化策略的评估和规划 · 应用现代化策略的 5R 模式 · 微服务架构设计的最佳实践 · 总结
P7P8架构师带你剖析业务架构与业务系统重构实践 实战电商与营销业务新风暴NX
09-14
├─01-《剖析业务架构与业务系统重构实践》.mp4 ├─02-《交易系统总体架构与设计》.mp4 ├─03-购物车架构与设计.mp4 ├─04-购物车架构与设计.mp4 ├─05-结算页架构与设计.mp4 ├─06-结算页架构与设计二.mp4 ├...
遗留系统重构与维护
05-04
遗留系统重构与维护,火龙果软件课程讲义,着重介绍软件维护思想
架构学习——业务架构
zwb的博客
05-08 1万+
一、什么是业务架构业务架构,顾名思义就是对于产品的业务架构进行梳理和整合,它表达的是业务系统之间的关系,帮助开发人员梳理业务结构。 二、为什么要画业务架构业务架构帮我们更好的从宏观的角度整体性的审查我们的产品 帮助用户和需求方从业务角度出发更好的了解我们的产品功能 有了业务架构我们可以更好的对目前已有的功能和以后计划开发的功能进行抽象、设计、开发 三、如何画业务架构? 站在巨人的肩膀上 我们要学会站在巨人的肩膀上学习,先看看一些比较牛的公司他们是怎么画的业务架构,借鉴他人的画法和思
系统重构思路
最新发布
软软的铲屎官的博客
05-10 693
现在是进行重构的恰当时机吗?重构前需要做什么准备?如何保障重构工作顺利完成并达成预期目标?从这几个大家都关心的问题,来谈谈重构工作遵循的基本思路和原则。
软件开发 —— 重构(refactor)
weixin_30909575的博客
07-22 227
0. 代码坏味道 Large Class,过大的类;Large method,过长的(成员)函数; 1. 基本内涵 在不改变代码外在行为的前提下对代码做出修改,以改进代码的内部结构的过程。 —— 《重构》(Martin Fowler) 只是为什么要修改已经能够工作的内部结构呢?代码模块的能够工作不是唯一要求。每一个软件模块都具有三种职责。 第一个职...
【案例分析之重构方案】
qq_31532979的博客
03-04 903
通过重新构建架构,可以解决远程无人干预情况下的升级和调试需求。采用可靠的技术选型和合适的架构设计,确保系统具有稳定性、连续性和安全性,并能满足使用场景的需求。技术委员会的管理和管控确保了技术的正确使用和发展。
系统架构重构
微软新技术
02-13 1574
下面,我们针对系统架构和设计中的“坏味”(注:“坏味”是 Martin Fowler 的一个著名概念),分别总结出的一些“重构模式”,看看这些模式是如何把这些设计“坏味”去掉的。1,实体重新命名问题:进行架构和设计时所界定出来的系统组成元素(子系统、构件、模块等)名称使用混乱,不能很好地表达该系统元素的用途或语义,使系统结构难以理解。事实上,一个架构发展的历程中,命名的逐渐混乱,是促使架构老化的重
项目重构方案设计
02-21
然后我们的任务就是对它进行重构,这个项目是一个功能很齐全的WPF视频播放器(附带很多其他功能),在仔细研究了项目的背景和架构以后,初步做出了一下的重构方案:目前现状:虽然整个系统做得很漂亮,代码也写得...
新一代医疗管理信息系统重构
06-28
新一代医疗管理信息系统重构 新一代医疗管理信息系统重构是医疗行业的未来发展方向。医院管理信息系统(HIS)经过多年的发展,已经从财务管理领域扩展到医嘱、LIS、PACS、EMR 等业务系统,成为医疗信息化的核心系统...
软件架构设计-基于重构
12-15
针对软件开发中的架构设计法论,采用递进的方式对旧有系统进行架构改造方法论
JAVA系统重构
12-20
通过重构改善现有的系统
重构pdf文档
11-14
重构(Refactoring)就是在不改变软件现有功能的基础上,通过调整程序代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性.
重构建议文档(第一版)
04-12
重构建议文档第一版:给出对.net代码的重构建议以及代码范例。
系统重构.pdf 侯捷
11-27
系统重构 讲如何重构代码和系统 系统重构 讲如何重构代码和系统 系统重构 讲如何重构代码和系统 系统重构 讲如何重构代码和系统 系统重构 讲如何重构代码和系统
项目重构方案模板、ppt
05-25
项目重构方案模板、项目重构方案模板ppt,项目重构方案计划模板
如何设计可落地的重构技术方案——理论篇
bytearch
05-31 1312
一、 写在前面最近重构项目比较多,写了好几个系统重构方案,很多朋友问,写重构技术方案,有没有什么套路或者框架,都需要做哪些调研和准备工作,这篇文章就重点聊一聊,如何设计可落地的重构方案。二、重构有没有套路有套路,多年重构经验表明,我重构已经形成了自己的一套固定模式,然后在这套模式之上,根据业务场景不断的变通,可以说,重构是经验的积累。所以在设计重构方案阶段,就能够避免一些...
系统重构的步骤
gjcandxyx的博客
07-15 1503
概述 随着公司业务不断的发展,用户量不断的增加,对系统的性能要求会越来越高,而原来仓促做出来的项目,其不合理性的地方就会不断的暴露出来。大家如果接触过非常赚钱的互联网产品,一定会知道产品的一个小小的bug,公司就可能损失好几百万甚至几个亿。当产品的用户数达到一定量的时候,对系统的各个方面的要求就越高,例如qps、cpu、容灾、降级、限流、可扩展性、可维护性等等。系统除了要应付大量的并发请求,还必须快速支持各种业务需求,必须对系统进行大重构。 备注: 下面的一些步骤和方式是根据我自己的项目的实际列出的。 业务
大型系统重构的步骤简单梳理
热门推荐
Sam_Deep_Thinking
07-14 1万+
目前正在参与公司一个核心大系统重构工作。本文梳理一下大型系统重构的一些步骤和心得。
如何重构一个校园招聘系统
02-16
2. 设计架构:根据需求设计新的系统架构,包括数据库设计、系统组成部分、数据流、用户界面等。 3. 选择技术:根据需求和系统架构选择适当的技术和工具。 4. 编写代码:根据设计的系统架构和技术选型开始编写代码...

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • android studio 的下拉菜单Spinner使用详解 62655
  • 对于云计算,大数据和人工智能与物联网的认识及理解 42877
  • 【Java基础知识】java调用并执行shell脚本 33021
  • 【ClickHouse】Clickhouse中update/delete的使用 19016
  • 【数据结构】单链表初始化 15574

分类专栏

  • 云原生系列 23篇
  • 大数据系列 11篇
  • 人工智能系列 5篇
  • 编程语言系列 1篇
  • Java 68篇
  • Golang 39篇
  • SpringBoot 45篇
  • Python 2篇
  • PHP 2篇
  • 架构设计系列 27篇
  • 分布式设计
  • 最佳实践 14篇
  • 设计模式 5篇
  • 算法和数据结构 16篇
  • 数据库技术系列 6篇
  • MySQL 25篇
  • 中间件系列
  • Redis 17篇
  • 消息队列 12篇
  • 服务运维系列 15篇
  • 网络编程 16篇
  • Nginx 10篇
  • 前端技术系列 19篇
  • 移动开发系列 2篇
  • bug采坑笔记 25篇
  • 工具安装教程系列 55篇
  • 技术打杂系列
  • 高质量编码 11篇

最新评论

  • 【架构设计】服务之间的调用为啥不直接用 HTTP 而用 RPC?

    我爱学习hahaha: 谢谢大佬啊!

  • Go 性能优化之pprof 实战

    沐暖春笙: 写得很好表情包

  • 【最佳实践】携程ClickHouse日志分析实践

    试剑江湖。: 更新不频繁的话可以考虑压缩json字符串、缓存等方式; 更新频繁的话优先确定字段;

  • 【最佳实践】携程ClickHouse日志分析实践

    Chowhounds: 你好,想请教一下,存储数据中每个字段都不确定,我们先用一个json存储了,但是查询的时候很慢,有什么好的方案来处理这种大的json吗?

  • Go GC之三色标记算法

    恋喵大鲤鱼: 为什么 Go GC 讲着讲着变成了 JVM 的 GC 呢?

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • 消息队列之关于如何实现延时队列
  • 【MySQL】事务
  • redis 缓存设计
2023年26篇
2022年47篇
2021年97篇
2020年207篇
2019年78篇
2018年16篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

试剑江湖。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

深圳SEO优化公司塘坑品牌网站设计报价烟台SEO按天收费价格佛山建网站公司贺州至尊标王公司眉山网站推广工具多少钱铜川优化价格张家界网站优化排名报价资阳seo网站优化庆阳百度竞价包年推广哪家好泰州网站优化排名公司唐山网站关键词优化公司达州seo公司天门百搜标王哪家好石岩网站建设飞来峡品牌网站设计哪家好林芝网站推广方案价格曲靖营销网站推荐本溪关键词排名公司马鞍山关键词按天计费哪家好北京高端网站设计吉祥网站优化按天计费公司坑梓百度网站优化排名公司湘西seo排名连云港关键词排名推荐通化关键词按天扣费多少钱云浮建站推荐广元百度网站优化公司西宁营销型网站建设多少钱无锡网站优化按天计费哪家好桂林SEO按效果付费多少钱歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化