主頁 >  其他 > KubeSphere 助力提升研發效能的應用實踐分享

KubeSphere 助力提升研發效能的應用實踐分享

2023-04-21 07:53:07 其他

作者:盧運強,主要從事 Java、Python 和 Golang 相關的開發作業,熱愛學習和使用新技術;有著十分強烈的代碼潔癖;喜歡重構代碼,善于分析和解決問題,原文鏈接,

我司從 2022 年 6 月開始使用 KubeSphere,到目前為止快一年時間,簡要記錄下此程序中的經驗積累,供大家參考,

背景

公司當前有接近 3000 人的規模,主要業務為汽車配套相關的軟硬體開發,其中專門從事軟體開發約有 800 人,這其中 Java 開發的約占 70%,余下的為 C/C++ 嵌入式和 C# 桌面程式的開發,

在 Java 開發部分,約 80% 的都是 Java EE 開發,由于公司的業務主要是給外部客戶提供軟硬體產品和咨詢服務,在早期公司和部門更關注的是如何將產品銷售給更多的客戶、獲得更多的訂單和盡快回款,對軟體開發流程這塊沒有過多的重視,故早期在軟體開發部分不是特別規范化,軟體開發基于專案主要采用敏捷開發或瀑布模型,而對于軟體部署和運維依舊采用的純手工方式,

隨著公司規模的擴大與軟體產品線的增多,上述方式逐漸暴露出一些問題:

  • 存在大量重復性作業,在軟體快速迭代時,需要頻繁的手工編譯部署,耗費時間,且此程序缺乏日志記錄,后續無法追蹤審計;
  • 缺乏審核功能,對于測驗環境和生產環境的操作需要審批流程,之前通過郵件和企業微信無法串聯;
  • 缺乏準入功能,隨著團隊規模擴大,人員素質參差不齊,需要對軟體開發流程、代碼風格都需要強制固化;
  • 缺乏監控功能,后續不同團隊、專案采用的監控方案不統一,不利于知識的積累;
  • 不同客戶的定制化功能太多(logo,字體,IP 地址,業務邏輯等),采用手工打包的方式效率低,容易遺漏出錯,

在競爭日益激烈的市場環境下,公司需要把有限的人力資源優先用于業務迭代開發,解決上述問題變得愈發迫切,

選型說明

基于前述原因,部門準備選用網路上開源的系統來盡可能的解決上述痛點,在技術選型時有如下考量點:

  • 采用盡量少的系統,最好一套系統能解決前述所有問題,避免多個系統維護和整合的成本;
  • 采用開源版本,避免公司內部手工開發,節約人力;
  • 安裝程序簡潔,不需要復雜的操作,能支持離線安裝;
  • 檔案豐富、社區活躍、使用人員較多,遇到問題能較容易的找到答案;
  • 支持容器化部署,公司和部門的業務中自動駕駛和云仿真相關的越來越多,此部分對算力和資源提出了更高的要求,

我們最開始采用的是 Jenkins,通過 Jenkins 基本上能解決我們 90% 的問題,但依舊有如下問題影使用體驗:

  • 對于云原生支持不太好,不利于部門后續云仿真相關的業務使用;
  • UI 界面簡陋,互動方式不友好(專案構建日志輸出等);
  • 對于專案,資源的權限分配與隔離過于簡陋,不滿足多專案多部門使用時細粒度的區分要求,

在網路上查找后發現類似的工具有很多,經過初步對比篩選后傾向于 KubeSphere、Zadig 這 2 款產品,它們的基本功能都類似,進一步對比如下:

KubeSphere Zadig
云原生支持 一般
UI 美觀度 一般
GitHub Star 12.4k 2k
社區活躍度 一般

經過對比,KubeSphere 較為符合我們的需求,尤其是 KubeSphere 的 UI 界面十分美觀,故最終選定 KubeSphere 作為部門內部的持續集成與容器化管理系統!

至此,部門內部經歷了手工操作->Jenkins->KubeSphere這 3 個階段,各階段的主要使用點如下:

實踐程序

KubeSphere 在公司內部的整體部署架構如下圖所示,其作為最頂層的應用程式直接與使用人員互動,提供主動/定時觸發構建、應用監控等功能,使用人員不必關心底層的 Jenkins、Kubernetes 等依賴組件,只需要與 Gitlab 和 KubeSphere 互動即可,

持續集成

初始實作

在最初的嘗試階段只規劃了 4 套環境:dev(開發環境)、sit(除錯環境)、test(測驗環境)、prod(生產環境),

出于簡化使用與維護的考慮,計劃對每個工程模塊只維護一條流水線,通過構建時選擇不同的環境引數來實作定制化打包與部署,

KubeSphere 和 Kubernetes 目前在部門是以單機版形式安裝的,故對于不同環境的區分主要是通過分配不同埠來實作,具體實作時需要能在 Jenkins 和 Kubernetes 的 yaml 檔案中都能動態的獲取對應的埠引數和專案名稱,參考實作代碼如下:

  • 在基于Groovyscript中根據選擇環境動態分配相關埠

    switch(PRODUCT_PHASE) {
        case "sit":
            env.NODE_PORT = 13003
            env.DUBBO_PORT = 13903
            break
        case "test":
            env.NODE_PORT = 14003
            env.DUBBO_PORT = 14903
            break
        case "prod":
            env.NODE_PORT = 15003
            env.DUBBO_PORT = 15903
            break
    }
    
  • script中讀取引數

    print env.DUBBO_IP
    
  • shell中讀取引數

    docker build -f kubesphere/Dockerfile \
    -t idp-data:$BUILD_TAG  \
    --build-arg  PROJECT_VERSION=$PROJECT_VERSION \
    --build-arg  NODE_PORT=$NODE_PORT \
    --build-arg  DUBBO_PORT=$DUBBO_PORT \
    --build-arg PRODUCT_PHASE=$PRODUCT_PHASE .
    
  • yaml檔案中讀取引數

    spec:
      ports:
        - name: http
          port: $NODE_PORT
          protocol: TCP
          targetPort: $NODE_PORT
          nodePort: $NODE_PORT
        - name: dubbo
          port: $DUBBO_PORT
          protocol: TCP
          targetPort: $DUBBO_PORT
          nodePort: $DUBBO_PORT
      selector:
        app: lucumt-data-$PRODUCT_PHASE
      sessionAffinity: None
      type: NodePort
    

運行效果類似下圖:

詳細內容請參見KubeSphere 使用心得,

環境擴容

基于前述方式搭建的 4 套環境一開始使用較為順利,但隨著專案的推進以及開發人員的增多,同時有多個功能模塊需要并行開發與測驗,導致原有的 4 套環境不夠用,經過一番摸索后,實作了結合 Nacos在 KubeSphere 中動態配置多套環境功能,通過修改 Nacos 中的JSON組態檔可很容易的從 4 套擴展為 16 套甚至更多,

結合專案實際情況以及避免后續再次修改 KubeSphere 流水線,為了實作靈活的配置多套環境,制定了如下 2 個規則:

  1. 埠資訊存放到組態檔中,KubeSphere 在構建時去流水線讀取相關配置
  2. 當需要擴展環境或修改埠時,不需要修改 KubeSphere 中的流水線,只需要修改對應的埠組態檔即可

由于專案中采用 Nacos 作為配置中心與服務管理平臺,故決定采用 Nacos 作為埠的配置中心,實作流程如下:

基于上述流程,在具體實作時面臨如下問題:

  • 利用 Groovy 代碼獲取 Nacos 中特定的埠 JSON 組態檔,并能動態決議;
  • 利用 Groovy 代碼根據輸入輸入引數動態的獲取 Nacos 中對應的 namespace
  • 由于環境的增多,不可能每套環境都準備一個 YAML 檔案,此時需要動態的讀取并更新 YAML 檔案,

由于 Jenkins 默認不支持 JSONYAML 的決議,需要在 Jenkins 中預先安裝 Pipeline Utility Steps插件,該插件提供了對 JSONYAMLCSVPROPERTIES 等常見檔案格式的讀取與修改操作,

  • JSON 檔案設計如下,通過 env、server、dubbo 等屬性記錄環境和埠資訊,通過 project 來記錄具體的專案名稱,由于組態檔中的 key 都是固定的,后續 Groovy 決議時會較為方便,在需要擴展環境時只需要更新此 JSON 檔案即可,

    {
        "portConfig":[
            {
                "project":"lucumt-system",
                "ports":[
                    {
                        "env":"dev-1",
                        "server":12001,
                        "dubbo":12002
                    },
                    {
                        "env":"dev-2",
                        "server":12201,
                        "dubbo":12202
                    }
                ]
            },
            {
                "project":"lucumt-idp",
                "ports":[
                    {
                        "env":"dev-1",
                        "server":13001,
                        "dubbo":13002
                    },
                    {
                        "env":"dev-2",
                        "server":13201,
                        "dubbo":13202
                    }
                ]
            }
        ]
    }
    
  • Nacos Open Api 中可知查詢 namespace 的請求為 /nacos/v1/console/namespaces,查詢組態檔的請求為 /nacos/v1/cs/configs,基于 Groovy 的讀取代碼如下:

    response = sh(script: "curl -X GET 'http://xxx.xxx.xxx.xxx:8848/nacos/v1/console/namespaces'", returnStdout: true)
    jsonData = https://www.cnblogs.com/kubesphere/p/readJSON text: response
    namespaces = jsonData.data
    for(nm in namespaces){
        if(BUILD_TYPE==nm.namespaceShowName){
            NACOS_NAMESPACE = nm.namespace
        }
    }
    
    response = sh(script:"curl -X GET 'http://xxx.xxx.xxx.xxx:8848/nacos/v1/cs/configs?dataId=idp-custom-config.json&group=idp-custom-config&tenant=0f894ca6-4231-43dd-b9f3-960c02ad20fa'", returnStdout: true)
    jsonData = https://www.cnblogs.com/kubesphere/p/readJSON text: response
    configs = jsonData.portConfig
    for(config in configs){
        project = config.project
        if(project!=PROJECT_NAME){
           continue
        }
        ports = config.ports
        for(port in ports){
            if(port.env!=BUILD_TYPE){
                continue
            }
            env.NODE_PORT = port.server
    	}
    }
    
  • 動態更新 yaml 檔案

    yamlFile = 'src/main/resources/bootstrap-dev.yml'
    yamlData = https://www.cnblogs.com/kubesphere/p/readYaml file: yamlFile
    yamlData.spring.cloud.nacos.discovery.group = BUILD_TYPE
    yamlData.spring.cloud.nacos.discovery.namespace = NACOS_NAMESPACE
    yamlData.spring.cloud.nacos.config.namespace = NACOS_NAMESPACE
    sh"rm $yamlFile"
    
    writeYaml file: yamlFile, data: yamlData
    

詳細內容請參見利用 Nacos 與 KubeSphere 創建多套開發與測驗環境,

擴展功能

  • 在專案構建時添加審核功能,對于 testprod 環境必須經過相關人的審核才能進行后續構建流程,避免破壞相關版本的穩定性,

  • 在 KubeSphere 的容器組頁面可以查看 pod 節點的 CPU 和記憶體消耗,可初步滿足對代碼潛在性能問題的排查,

  • 在專案構建完成時發送郵件通知給相關人,

外部部署

部門內部的軟體最終都會銷售并交付給相關客戶,由于客戶網路與公司網路不通以及代碼保密等要求,無法在客戶現場使用原有的 Jenkins 流水線進行部署交付,基于此部門采取折中方案:在公司內部通過 KubeSphere 進行編譯打包,匯出 Docker 鏡像,拷貝到客戶處然后基于 Docker 鏡像部署運行,具體請參見如下鏈接:

  • 在 Jenkins 中根據配置從不同的倉庫中 Checkout 代碼
  • 利用 shell 腳本實作將微服務程式以 docker 容器方式自動部署

使用協助

在使用程序中確實遇到了不少問題,主要通過如下三條途徑解決:

  • 閱讀官方檔案,根據檔案說明操作;
  • 若官網檔案沒有,則去用戶論壇查看是否有人遇到類似問題或直接發帖;
  • 通過微信群尋求協助,

根據部門使用經驗,90% 的問題可通過官方檔案或用戶論壇獲得答案,

使用效果

部分同事習慣于原始的手工操作或基于 Docker 部署,導致在推廣程序中受到了一定的阻力,部門內部基于充分溝通和逐步替換的方式引導相關同事來慢慢適應,經過約一年的時間磨合,大家都認可了擁抱云原生和 KubeSphere 給我們帶來的便利,使用過的同事都說很香!

對我司而言,有如下幾個方面的提升:

  • 研發人員幾乎不用耗費時間在軟體的部署和監控上,節省約 20% 時間,產品迭代速度更快;
  • 定制化的功能通過腳本實作,徹底杜絕了給客戶交付軟體時由于人工疏漏導致的偶發問題,在提高軟體交付質量的同時也提升了客戶我司的認可度;
  • 軟體開發、測驗流程更規范,通過在 Jenkins 流水線強制添加各種規范檢查和審核流程,實作了軟體研發的規范統一,代碼質量更高,更利于擴展維護,同時也在一定程式上減少了由于人員流失/變更對專案造成的影響;
  • 基于 KubeSphere 的云原生部署結合 Nacos 可以更快速的分配多套環境,有效的實作了開發測驗生產環境的隔離,在云仿真相關的業務場景中可基于業務場景更方便的對 pod 進行監控與調整,前瞻性的業務研發開展更順利,

未來規劃

結合公司與部門的實際情況,短期的規劃依然是完善基于 Jenkins 的 CI/CD 使用來完善打包與部署流程,部門內部在進行全面 web 化,基于此中長期擁抱云原生,

  • 接入企業微信,將構建與運行結果隨時通知相關人,構建結果與專案監控更實時;
  • 將部門內部基于 Eclipse RCP 的桌面應用程式通過 Jenkins 實作標準化與自動化的構建;
  • 將底層的 Kubernetes 從單機升級為集群,支持更多 pod 的部署,支持公司內部需要大量 pod 并發運行的云仿真專案;
  • 部門內部的 web 專案全部通過 KubeSphere 構建部署,完善其使用檔案,挖掘 KubeSphere 在部門業務中新的應用場景(如對設計檔案、開發檔案、bug 修復的定時與強制檢查通知等),

本文由博客一文多發平臺 OpenWrite 發布!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/550670.html

標籤:其他

上一篇:云原生2.0網關API標準發展趨勢

下一篇:返回列表

標籤雲
其他(157713) Python(38083) JavaScript(25376) Java(17984) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • KubeSphere 助力提升研發效能的應用實踐分享

    作者:盧運強,主要從事 Java、Python 和 Golang 相關的開發作業。熱愛學習和使用新技術;有著十分強烈的代碼潔癖;喜歡重構代碼,善于分析和解決問題。原文鏈接。 我司從 2022 年 6 月開始使用 KubeSphere,到目前為止快一年時間,簡要記錄下此程序中的經驗積累,供大家參考。 ......

    uj5u.com 2023-04-21 07:53:07 more
  • 云原生2.0網關API標準發展趨勢

    摘要:Gateway API希望取代Ingress API。 本文分享自華為云社區《云原生2.0網關API標準發展趨勢》,作者:華為云云原生團隊 。 云原生網關API標準背景及發展現狀 Gateway API是一個開源的API標準,源自Kubernetes SIG-NETWORK興趣組。從出身角度講 ......

    uj5u.com 2023-04-21 07:52:04 more
  • 常用內核架構

    本文分享自天翼云開發者社區《常用內核架構》,作者:JackW 宏內核 應用程式呼叫記憶體分配的 API(應用程式介面)函式。 處理器切換到特權模式,開始運行內核代碼。 內核里的記憶體管理代碼按照特定的演算法,分配一塊記憶體。 把分配的記憶體塊的首地址,回傳給記憶體分配的 API 函式。 記憶體分配的 API 函式 ......

    uj5u.com 2023-04-21 07:51:28 more
  • 貪心演算法基礎及leetcode例題

    參考 #理論 **本質:**找到每個階段的區域最優,然后去推導得到全域最優 **兩個極端:**常識&&很難: 很多同學通過了貪心的題目,但都不知道自己用了貪心演算法,因為貪心有時候就是常識性的推導,所以會認為本應該就這么做! 套路: 貪心沒有套路,說白了就是常識性推導加上舉反例 做題的時候,只要想清楚 ......

    uj5u.com 2023-04-21 07:51:13 more
  • 【ACM演算法競賽日常訓練】DAY16【奇♂妙拆分】【區區區間間間】

    DAY16共3題: 奇♂妙拆分(簡單數學) 區區區間間間(單調堆疊) 小AA的數列(位運算dp) 🎈 作者:Eriktse 🎈 簡介:19歲,211計算機在讀,現役ACM銀牌選手🏆力爭以通俗易懂的方式講解演算法!??歡迎關注我,一起交流C++/Python演算法。(優質好文持續更新中……)🚀 🎈 ......

    uj5u.com 2023-04-21 07:51:04 more
  • 圖計算引擎分析--GridGraph

    GridGraph是一種單機核外圖處理系統,在大規模圖處理系統中充分利用磁盤讀寫,在有限記憶體中高效完成大規模圖計算。GridGraph充分利用磁盤大容量,解決單機記憶體有限時實作大規模圖計算問題。GridGraph采用Streaming-Apply方式減少計算中的IO 請求數量,通過檔案調入順序減少不... ......

    uj5u.com 2023-04-21 07:50:06 more
  • 護士排班

    護士排班問題是一種經典的優化問題,它的目標是為醫院的護士制定一個合理的排班計劃,以確保醫院的正常運轉。在本篇文章中,我們將介紹護士排班問題的背景、演算法思路以及實作方法。 一、背景 護士排班問題是一種 NP 難問題,它的目標是為醫院的護士制定一個合理的排班計劃,以確保醫院的正常運轉。在醫院中,護士的工 ......

    uj5u.com 2023-04-21 07:49:22 more
  • 時而實踐、時而學習

    讀毛選、林語堂的《蘇東坡傳》和德魯克的《卓有成效的管理》有感!提升自己的作業方法、管理方法和思想境界。 ......

    uj5u.com 2023-04-21 07:48:34 more
  • 詳解資料結構中堆疊的定義和操作

    摘要:本文為大家詳解資料結構中堆疊的定義和操作。 本文分享自華為云社區《資料結構:詳細講解堆疊的定義、堆疊的操作》,作者: 高彬滔 。 1.堆疊的定義 堆疊(stack):是只允許在一端進行插入或者洗掉操作的線性表(即后進先出,大概可以理解為吃飽了吐出來) 空堆疊:不含元素的空標配 堆疊頂:表尾端 堆疊底:表頭端 ......

    uj5u.com 2023-04-21 07:48:18 more
  • 數字先鋒 | 乘“云”之勢,天翼云助力長春市婦產醫院步入智慧醫療

    近年來,大資料、云計算、5G等新興技術逐步融入衛生健康服務各個領域,驅動傳統醫療衛生服務向數字健康發展階段邁進。各地醫療機構積極回應國家號召,推進醫院資訊化建設提檔升級,加快資訊系統云上部署,我國醫療行業正逐步邁向數字化轉型新階段。 長春市婦產醫院始建于1896年,是一所集預防、保健、醫療、康復、科 ......

    uj5u.com 2023-04-21 07:48:01 more