国产精品chinese,色综合天天综合精品网国产在线,成午夜免费视频在线观看,清纯女学生被强行糟蹋小说

    <td id="ojr13"><tr id="ojr13"><label id="ojr13"></label></tr></td>
        • <source id="ojr13"></source>
            <td id="ojr13"><ins id="ojr13"><label id="ojr13"></label></ins></td>

            Article / 文章中心

            你管這破玩意兒叫上云?

            發(fā)布時(shí)間:2022-03-15 點(diǎn)擊數(shù):696
            現(xiàn)在上云可以說是業(yè)界公認(rèn)的趨勢(shì)了,因?yàn)橄癜⒗镌?,騰訊云等云廠商提供的工具真的太全了,基本上覆蓋了一個(gè)大廠系統(tǒng)所需的方方面面,不信?

            大家好,我是坤哥。

            好久沒更了,最近幾周身體不好,得了比較嚴(yán)重的胃炎+心動(dòng)過速癥狀,跑了好幾趟醫(yī)院,嚴(yán)重的時(shí)候心臟感覺很不舒服,胸悶氣短,有瀕死感,有時(shí)幾乎整夜睡不好覺,在此奉勸大家還是要保重身體,千萬不要做熬夜等傷身體的傻事,千萬保重身體!

            年前和年后我們完成了一次從 0 到 1 的上云之旅,其中踩了不少坑,也積累了不少寶貴的經(jīng)驗(yàn),所以在此總結(jié)成文,相信大家看了肯定有收獲。

            先說下此次上云的背景,創(chuàng)業(yè)后,我們的業(yè)務(wù)是從集團(tuán)中獨(dú)立出來了,不過系統(tǒng)還是和集團(tuán)共用的,共用系統(tǒng)本來也不是個(gè)事兒,但由于集團(tuán)早已今非昔比,核心人員都走得差不多了,導(dǎo)致一些核心系統(tǒng)不穩(wěn)定,甚至出現(xiàn)過反向代理層宕機(jī)無人修復(fù)而導(dǎo)致整個(gè)交易跌零的嚴(yán)重事故,所以我們決定將系統(tǒng)完全從集團(tuán)中剝離出來,由于之前集團(tuán)系統(tǒng)上云采用的是騰訊云,所以我們也用了騰訊云,這樣網(wǎng)絡(luò)可以做到互通,共用一些待遷移的系統(tǒng)的鏡像,也可以用騰訊云的工具對(duì)數(shù)據(jù)進(jìn)行增量/全量遷移等以降低遷移成本。

            云服務(wù)都有哪些

            現(xiàn)在上云可以說是業(yè)界公認(rèn)的趨勢(shì)了,因?yàn)橄癜⒗镌?,騰訊云等云廠商提供的工具真的太全了,基本上覆蓋了一個(gè)大廠系統(tǒng)所需的方方面面,不信?我們不妨一起來看看,先來看下大廠的基本系統(tǒng)架構(gòu):

            編輯搜圖

            可以看到一個(gè)完整的可運(yùn)行的系統(tǒng)需要提供:DNS 解析,CDN 服務(wù),接入層,中間件,存儲(chǔ)層,APM 等,云上這些工具全有 ,而且基本都是一鍵部署,這里簡(jiǎn)單舉兩個(gè)例子:

            • 以部署 ZK 集群為例,如果你要部署一個(gè) ZK 集群,那一般要在三臺(tái)虛擬機(jī)上部署(ZK集群要求至少提供三臺(tái)服務(wù)器),還需要編輯配置文件等,涉及到這種人為的工作往往比較容易繁瑣,而且容易出錯(cuò),但在騰訊云上點(diǎn)個(gè)按鈕就可以自動(dòng)幫你生成一個(gè) ZK 集群,你所要做的只需在工程中替換此 ZK 集群地址,同時(shí)還可以查看它的基本信息(部署架構(gòu)),數(shù)據(jù)管理,運(yùn)行監(jiān)控(JVM,連接數(shù),內(nèi)存使用率等),運(yùn)行日志。

            • 再比如你要部署一個(gè) Redis 分片集群,一開始可能只需要一個(gè)分片,但后面隨著業(yè)務(wù)的發(fā)展,需要進(jìn)行分片擴(kuò)容,那就比較麻煩了,一般需要用官方提供的 redis-trib 管理軟件進(jìn)行遷移,涉及到創(chuàng)建新的節(jié)點(diǎn),將新的主節(jié)點(diǎn)加入集群,轉(zhuǎn)移slot(重新分片),將從節(jié)點(diǎn)加入集群這些步驟,很煩瑣,但如果用騰訊云本身提供的工具,只要選擇對(duì)應(yīng)的分片選項(xiàng),再點(diǎn)確定,即可一鍵搞定(如下),非常方便,同樣的,騰訊云也提供了 Redis 的緩存命中率,慢查詢,CPU 使用率等監(jiān)控。

            編輯搜圖

            以上只是簡(jiǎn)單舉了兩個(gè)例子,事實(shí)上,像 MySQL,ES,MQ 等組件騰訊云上也基本都提供了一鍵式生成的操作,并且都附帶了相關(guān)的監(jiān)控與告警機(jī)制,極大地降低了運(yùn)維成本,使用這些工具唯一的缺點(diǎn)就是:

            編輯搜圖

            但我們也有一些控制成本的手段 ,比如:

            • 如果項(xiàng)目是內(nèi)網(wǎng)的話(如運(yùn)營(yíng)中心等),完全可以把這些項(xiàng)目都部署在同一臺(tái)低配的虛擬機(jī)上以節(jié)省成本。

            • 線上多個(gè)前端項(xiàng)目也可以同時(shí)部署在同一臺(tái)機(jī)器上,配合 CDN 可以解決訪問過慢的問題。

            • 我們需要部署 APM(查看分布式調(diào)用鏈,JVM 監(jiān)控等),就得在機(jī)器上部署 Skywalking 這樣的分布式追蹤框架以便采集數(shù)據(jù),如果在每個(gè)服務(wù)的每臺(tái)機(jī)器上都采集其實(shí)沒有必要,成本也比較高,所以我們后來調(diào)整為了每個(gè)服務(wù)只有一臺(tái)機(jī)器進(jìn)行采集,并且降低了采樣率,這樣上傳的數(shù)據(jù)就少很多,可以降低成本,采用這樣的方式之后, skywalking 的采集數(shù)據(jù)成本只需要每天 10 元左右。

            數(shù)據(jù)遷移

            由于我們之前的系統(tǒng)是與集團(tuán)共用的,現(xiàn)在要獨(dú)立成一套,那就必須搞獨(dú)立的配置中心,獨(dú)立的 Redis,獨(dú)立的 MQ,獨(dú)立的數(shù) DB......,所有的這一切都不是一蹴而就的,顯然需要做到數(shù)據(jù)的平滑遷移,具體的操作如下:

            • 數(shù)據(jù)庫(kù)遷移:使用騰訊云上的數(shù)據(jù)遷移服務(wù),進(jìn)行全量+增量的升級(jí),保證數(shù)據(jù)的一致性后再把數(shù)據(jù)源全部切成我們的庫(kù)。

            • 配置中心數(shù)據(jù)遷移:之前集團(tuán)使用的 ZK 作為配置中心,所以我們直接使用了一款開源好用的遷移工具 zkcopy,執(zhí)行以下命令即可完成 ZK 的數(shù)據(jù)遷移。

            復(fù)制
            java -jar target/zkcopy.jar --source server:port/path --target server:port/path1.
            

            Redis 遷移:另建一個(gè) Redis 實(shí)例(只是 host 不同),使用 AOP 的形式讓原 Redis(集團(tuán) Redis)在寫入后新 Redis 也一起寫入,這樣維持一周左右,基本上就能把 Redis 的數(shù)據(jù)遷移完畢,偽代碼如下:

            復(fù)制
            @Slf4j
            @Aspect
            @Component
            public class AopRedisReadWriteAspect {
            
              @Resource
              private RebateNewCacheClient rebateNewCacheClient;        // 新 Redis 實(shí)例// RedisCacheClient 即集團(tuán) Redis 實(shí)例,使用 AOP 的方式可以讓集團(tuán)的 Redis 寫入的同時(shí)也同步到我司的 Redis 實(shí)例來// 從而最終實(shí)現(xiàn)數(shù)據(jù)一致性
              @Around(value = "execution(* com.xxx.RedisCacheClient.setex(" +
                      "String,int,String)) && args(key,expire,value)")
              public Object setEx(ProceedingJoinPoint joinPoint, String key, int expire, String value) {
                  rebateNewCacheClient.setEx(key, expire, value);
                  return invokeOrigin(joinPoint);
              }private Object invokeOrigin(ProceedingJoinPoint joinPoint) {
              try {
                  return joinPoint.proceed();
              } catch (Throwable throwable) {
                  // 打印日志  }
              return null;
              }}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.
            
            • MQ 遷移:首先 MQ 的創(chuàng)建和 ZK 集群等創(chuàng)建一樣方便,我們要做的,只是確定好分區(qū)數(shù)等,確定好之后動(dòng)動(dòng)手指點(diǎn)擊一下,這樣就會(huì)一鍵生成一個(gè)高可用的 RocketMQ 集群,包括各種監(jiān)控,消息狀態(tài)查閱等也應(yīng)有盡有,如果你自己部署估計(jì)要搞半天,在遷移的時(shí)候,我們做了兩手準(zhǔn)備,一是同時(shí)向集團(tuán)和我司的 broker 發(fā)消息,然后灰度一部分用戶,這部分用戶只向我司的 broker 發(fā)消息,確認(rèn)沒問題后,再停掉發(fā)集團(tuán)的 broker 邏輯,這樣可以做到平穩(wěn)過渡。

            Ansible 簡(jiǎn)介

            雖然云上有很多服務(wù)可以幫助我們快速接入 Redis 等中間件,快速遷移 DB 等數(shù)據(jù),但除了這些基本上云服務(wù)可以提供的并不是說我們其他啥也不用干了,接下來我們來談下本文的重點(diǎn):項(xiàng)目部署的架構(gòu)設(shè)計(jì)。比如一個(gè) Java 項(xiàng)目,你要跑起來,總得先編譯打包(生成 jar 包)吧,打包之后發(fā)布總不能立馬中斷正在運(yùn)行的服務(wù)吧,你得用優(yōu)雅停機(jī)的方式來停掉服務(wù)然后再部署新包,部署之后如果發(fā)現(xiàn)有問題要回滾吧,這些步驟如果用手工操作肯定不現(xiàn)實(shí),最好的方式其實(shí)是寫成腳本的方式然后一鍵部署,不過一個(gè)服務(wù)可能有多臺(tái)機(jī)器,難道我們需要一臺(tái)臺(tái)登錄然后再手動(dòng)觸發(fā)相應(yīng)的部署腳本?顯然不現(xiàn)實(shí),更合理的方式是首先要把所有的這些部署步驟寫成腳本的形式,然后再用一個(gè)支持批量部署的自動(dòng)化運(yùn)維工具來部署,經(jīng)過調(diào)研,我們選擇了 Ansible。

            什么是 Ansbile ,它有什么優(yōu)勢(shì)?

            Ansible是一款簡(jiǎn)單的運(yùn)維自動(dòng)化工具,只需要使用ssh協(xié)議連接就可以實(shí)現(xiàn)批量系統(tǒng)配置、批量程序部署、批量運(yùn)行命令等功能。

            編輯搜圖

            ansbile 有以下幾個(gè)優(yōu)勢(shì):

            • 它是通過 SSH 來接管對(duì)應(yīng)機(jī)器的控制權(quán)的,對(duì)應(yīng)的機(jī)器無需安裝任何的 ansible 客戶端,也無需啟用額外的服務(wù),所以即便 ansible 升級(jí)也不影響對(duì)應(yīng)的機(jī)器;

            • 有大量常規(guī)運(yùn)維操作模塊,可實(shí)現(xiàn)日常絕大部分操作;

            • 配置簡(jiǎn)單、功能強(qiáng)大、擴(kuò)展性強(qiáng)

            • 通過 Playbooks(劇本) 來定制強(qiáng)大的配置、狀態(tài)管理,所謂劇本,即 YAML 格式文件,多個(gè)任務(wù)定義在此文件中,定義主機(jī)需要用哪些模塊(主要有核心模塊和自定義模塊)來完成這些功能。

            由于它的上述這些特點(diǎn),Ansible 很快流行了起來,甚至可以說是運(yùn)維必備的一款神器了,上圖是 Ansible 的極簡(jiǎn)版,我們?cè)偕晕⒄归_一下它的架構(gòu)看看:

            編輯搜圖

            它的執(zhí)行流程如下

            • 用戶登錄(一般通過跳板機(jī)) ansible 所在機(jī)器。

            • 通過 Host Inventory 來指定要控制的主機(jī),這個(gè)一般是個(gè) yaml 文件,我們可以在此文件中指定所有我們可以控制的 host,另外一個(gè)服務(wù)通常有多臺(tái)機(jī)器,我們也可以指定哪些機(jī)器屬于某個(gè)服務(wù),這里簡(jiǎn)單舉個(gè)例子:

            復(fù)制
            all:
             hosts:
               10.100.1.2:
                   10.100.1.4:
                   10.100.1.5:
             children:
               build:
                 hosts:
                   10.100.1.2:
               operation_center:
                 hosts:
                   10.100.1.4:
                   10.100.1.5:1.2.3.4.5.6.7.8.9.10.11.12.13.
            

            上圖中, 10.100.1.4,10.100.1.5即屬于同一個(gè)服務(wù)operator_center,如果我們到時(shí)要發(fā)布這個(gè)服務(wù)的話,只需要指定其服務(wù)名 operator_center 即可(下文會(huì)介紹)。

            • 通過步驟 2 我們即可指定需要操控哪些機(jī)器,然后 ansible 再通過連接模塊(即 Connection Plugins,采用 SSH 連接)連接步驟 2 中指定的 host 然后利用核心模塊(core modules)寫好相應(yīng)的 Playbooks 并執(zhí)行。

            ansible 的 core modules(核心模塊)有很多,功能也很強(qiáng)大,基本不需要自定義模塊,像我們這次上云也只用了核心模塊,來看幾個(gè)比較常見的模塊:

            • shell模塊:可以在遠(yuǎn)程主機(jī)上調(diào)用 shell 解釋器運(yùn)行命令,支持 shell 的各種功能,例如管道等。

            • copy 模塊:將文件復(fù)制到遠(yuǎn)程主機(jī),同時(shí)支持給定內(nèi)容生成文件和修改權(quán)限等。

            • file 模塊:設(shè)置文件的屬性,比如創(chuàng)建文件、創(chuàng)建鏈接文件、刪除文件等。

            • fetch模塊:從遠(yuǎn)程某主機(jī)獲取(復(fù)制)文件到本地(即 ansible 所在機(jī)器)。

            • command 模塊:在遠(yuǎn)程主機(jī)上執(zhí)行命令,并將結(jié)果返回到調(diào)用機(jī)上(也就是 ansible 所在主機(jī))。

            • cron 模塊:定時(shí)任務(wù)模塊,這個(gè)大家應(yīng)該比較熟悉了。

            我們知道一般工程都需要構(gòu)建(或者說打包,兩個(gè)概念相差不大)之后才能部署,比如 Java 工程要打包成 Jar 文件然后再部署(執(zhí)行 Jar 包),前端工程也需要打包后才能部署(比如把多個(gè) js 文件合并成一個(gè)以減少請(qǐng)求提升性能,再比如你可能使用 SCSS 或 less 來寫 CSS,也需要編譯成 CSS 文件,并且合并起來),那么問題來了,能否直接在生產(chǎn)機(jī)器上執(zhí)行打包操作呢?答案顯然是否定的,主要有兩個(gè)原因:

            • 打包由于采用了各種優(yōu)化手段(比如并行打包等)是很耗費(fèi) CPU 的,如果在生產(chǎn)上正在對(duì)外服務(wù)的機(jī)器上執(zhí)行打包操作的話,那么很可能由于打包時(shí)耗費(fèi)的 CPU 過大而導(dǎo)致當(dāng)前正在執(zhí)行的機(jī)器出現(xiàn)響應(yīng)太慢,拒絕請(qǐng)求等問題,這顯然是不可接受的。

            • 服務(wù)是以集群的形式存在的,可能一個(gè)服務(wù)有好幾臺(tái)機(jī)器,這些機(jī)器部署其實(shí)所需的 jar 包完全是一樣的,沒有必要在各個(gè)機(jī)器上都執(zhí)行一遍通過的打包操作。

            部署架構(gòu)設(shè)計(jì)

            綜上,我們需要一個(gè)專門的打包機(jī),將打包的工作交給打包機(jī),打包機(jī)打包好之后,我們?cè)侔严鄳?yīng)的包發(fā)到生產(chǎn)的機(jī)器上,然后再執(zhí)行部署腳本,架構(gòu)模型如下:

            編輯搜圖

            通過這樣的方式,打包機(jī)承擔(dān)了所有繁重的活,打包之后,ansible 會(huì)通過 fetch 模塊將這些 jar 包拉到本地,然后再通過 push 模塊把 jar 包 push 到服務(wù)集群上的所有機(jī)器,然后再執(zhí)行比較輕量級(jí)的部署腳本。

            介紹了這么多 Ansible 相關(guān)的概念,大家可能還是一臉懵逼,那么接下來我們一起來看下如何利用 Ansible 來執(zhí)行我們所設(shè)計(jì)的打包部署步驟,這樣大家對(duì) Ansible 的功能也能有更全面的認(rèn)識(shí)。

            樣例腳本我們一一介紹下:有三個(gè)文件

            1.production-hosts.yaml 文件:即我們上文提到的的 host inventory;

            復(fù)制
             #production-hosts.yaml
            
               all:
                 hosts:
                   10.100.1.2:
                       10.100.1.4:
                       10.100.1.5:
                 children:
                   build:        # 打包機(jī)
                     hosts:
                       10.100.1.2:
                   operation_center:   # operation_center 服務(wù)
                     hosts:
                       10.100.1.4:
                       10.100.1.5:1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.
            

            2.打包 playbook: java-build.yaml;

            復(fù)制
            # java-build.yaml- name: build project artifact
             hosts: build       // build 表示打包機(jī),定義在 production-hosts.yaml 文件中
             tasks:
               - name: Pull source code and checkout branch
                 ansible.builtin.git:
                   repo: '工程git地址'
                   dest: workspace/operation_center
                   version: master
                   force: yes   - name: Grant execute permission to build.sh
                 ansible.builtin.file:                                                  // file 模塊
                   path: workspace/operation_center/build.sh
                   mode: '0755'
               - name: Build project                                                        // 執(zhí)行打包腳本
                 ansible.builtin.shell: ./build.sh                          // shell 模塊
                 args:
                   chdir: workspace/operation_center
                   executable: /bin/bash   - name: Create archive project  // 打包后會(huì)生成 jar 包,創(chuàng)建目錄存放存放即將壓縮后的 jar 包
                 ansible.builtin.file:
                   path: archive/operation_center
                   state: directory
                 args:
                   chdir: /home/buser   - name: Archive latest artifact      // 壓縮 jar 包到上一步創(chuàng)建的目錄中
                 ansible.builtin.shell: cp workspace/operation_center/target/operation_center.jar archive/operation_center/latest.jar
                 args:
                   chdir: /home/buser   - name: Fetch project artifact to local      // 使用 fetch 模塊將上一步壓縮的 jar 包從打包機(jī)拉到 ansible 所在機(jī)器上
                 ansible.builtin.fetch:
                   src: archive/operation_center/latest.jar
                   dest: /tmp/operation_center/
                   flat: yes   - name: Fetch bin file to local      // 將部署腳本從打包機(jī)拉到本地,準(zhǔn)備傳給線上機(jī)器執(zhí)行部署操作
                 ansible.builtin.fetch:
                   src: /home/buser/workspace/operation_center/deploy.sh
                   dest: /tmp/operation_center/
                   flat: yes1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.
            

            3.部署 playbook: java-deploy.yaml;

            復(fù)制
            # java-deploy.yaml- name: Deploy project
             hosts: operation_center # 表示線上服務(wù)器,定義在 production-hosts.yaml 文件中
             serial: 1
             any_errors_fatal: true   # 只要一步失敗,部署流程即終止
             tasks:
               - name: Upload artifact & restart project
                 block:
                   - name: Push project artifact to remote   # 將 ansbile 上的 jar 包 push 到服務(wù)器上
                     ansible.builtin.copy:
                       src: /tmp/operation_center/latest.jar
                       dest: /opt/apps/business/operation_center.jar
                   - name: Push deploy file to remote       # 將 ansbile 上的部署腳本 push 到服務(wù)器上
                     ansible.builtin.copy:
                       src: /tmp/operation_center/deploy.sh
                       dest: /opt/apps/bin/
            
                   - name: Start operation_center
                     ansible.builtin.shell: bash bin/start.sh   # 執(zhí)行部署腳本
                     args:
                       chdir: /opt/apps
                       executable: /bin/bash
                     environment:
                       appEnv: prod       - name: Health check 8001                      # 健康檢查
                     uri:
                       url: http://127.0.0.1:8001/service/health/deepCheck
                       return_content: yes
                       status_code: -1
                     register: this
                     failed_when: "'health' not in this.content"
                     when: health_check == "8001"
                   - name: Health check 8081
                     uri:
                       url: http://127.0.0.1:8081/health/check
                       return_content: yes
                     register: this
                     failed_when: "'health' not in this.content"
                     when: health_check == "8081"
                 become: yes          # 在線上服務(wù)器上以 root 身份執(zhí)行上述的部署步驟
                 become_user: root1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.
            

            有了以上三個(gè)文件,只要分別執(zhí)行打包和部署操作 playbook 即可,如下:

            復(fù)制
            ansible-playbook -i production-hosts.yaml java-build.yaml     # 在打包機(jī)中打包
            ansible-playbook -i production-hosts.yaml java-deploy.yaml    # 在線上服務(wù)器上部署1.2.
            

            可以看到只要使用 ansible 的核心模塊即可完成我們的打包部署需求,執(zhí)行流程會(huì)通過上文中的 name 展示,部署流程部分展示如下:

            編輯搜圖

            可以看到整個(gè)流程部署流程非常的清晰!

            為了方便起見,以上腳本只是簡(jiǎn)單介紹了一下打包部署的部分步驟,其實(shí)我們還需考慮回滾等操作,由于不是本文的重點(diǎn),所以這里就不再做介紹了。

            聊點(diǎn)題外話

            現(xiàn)在各個(gè)云廠商提供的工具確實(shí)相當(dāng)廣泛,而且很好用了,基本每個(gè)開發(fā)都能承擔(dān) devops(開發(fā)運(yùn)維) 的工作,于是就有了一個(gè)擔(dān)憂:開發(fā)的工作到時(shí)會(huì)不會(huì)被替換,尤其是運(yùn)維就更有這樣的憂慮了,之前就有一位運(yùn)維哥們說這些云廠商工具這么好用,很擔(dān)心自己的飯碗被搶了,也確實(shí),畢竟基本上你能想到的運(yùn)維工作它都能一鍵點(diǎn)擊幫你做了,甚至"侵蝕"到數(shù)據(jù)庫(kù),中間件這些領(lǐng)域,曾經(jīng)一個(gè)數(shù)據(jù)庫(kù)團(tuán)隊(duì)的 Leader 反對(duì)上云,說了一大堆上云的缺點(diǎn),但他自己私下其實(shí)也說了,上云的趨勢(shì)已經(jīng)不可阻擋了,很擔(dān)心有一天會(huì)失業(yè) 。

            之前有一位讀者提到下面這樣的問題:

            我的回答是像這些其實(shí)云廠商都提供了很成熟的解決方案,基本一鍵生成,于是就有了這位讀者的靈魂拷問。

            我相信很多人也有這有這樣的疑問,我的看法是云服務(wù)廠商這些提供的只是工具,但如何利用好這些工具,還需要我們來操控,所以我給的建議如下:

            開發(fā)如果想向更高階發(fā)展,還是要掌握扎實(shí)的理論基礎(chǔ)與實(shí)戰(zhàn)經(jīng)驗(yàn)