您当前的位置:首页 > 电脑百科 > 程序开发 > 程序员

作为程序员,我们不能只管上线,不管线上!

时间:2023-08-31 15:10:38  来源:微信公众号  作者:Java极客技术

作为一名程序员,我们不能只关注代码的实现和上线,而忽视了线上环境的运行和优化。

近期遇到了两个线上服务的问题,一个后端应用和一个前端项目,它们存在一些 bug 和历史遗留问题。为了不影响用户的使用体验,决定对它们进行一次优化。

后端服务

这个后端服务是年初的时候有同事离职了,交到了我这里,没接手的时候不知道,没想到接手后,到处都是问题,天天各种报警,基本上隔三差五就要重启。

虽然一开始的时候知道这个服务不是很稳定,日常会有一些队列消息堆积,但是不在自己手上,不知道问题会这么多,动不动就堆积上亿条消息,天天慢 SQL 和高负载报警。

平时工作日的时候收到报警不是很在意,顺手重启一下就算了,但是当每次周末或者出门在外的时候,收到报警心里还是蛮荒的。

抱着做一个问题的终结者的想法,最后还是准备花时间把这个服务做一下手术,从根本上解决问题。

效果

先说一下效果,这个服务从优化过后,基本上除了迭代就再也没有需要重新启动过,更不存在隔三差五的重启,现在每天的报警量从之前的一天几百条变为 0,队列无任何堆积。

优化过程

优化的过程中最难的是发现问题,只要能精准的找到问题所在,解决起来还是很容易的。

优化主要分两步:1. 解决慢 SQL;2. 解决堆积报警;

慢 SQL

解决慢 SQL 的思路很简单,根据慢 SQL 日志,找到对应的慢 SQL 进行优化即可。优化可以从两个方向来进行,一种是基于 SQL 本身来进行优化,另一种是可以通过缓存来解决。这里需要根据具体的业务来选择,如果不是经常变动的数据,则可以通过增加缓存来解决,刚好我这里就可以满足。

经过分析可以通过增加 redis 缓存来解决这个问题,所以通过引入的 Redis 解决了慢 SQL 问题。

消息堆积

队列消息堆积的处理方式无非也就是两种,减少数据量,加快处理速度。

消息队列里面的消息因为是上游发过来的,没办法从发送方进行减少,不过分析了一下消息类型,发现有很多消息的类型是完全不需要关心的,所以第一步增加消息过滤,将无用的消息直接提交掉。

另外之前遇到消息堆积的时候,观察到消费消息的 TPS 特别低,有时候只有个位数,完全不正常,而且每次重启过后 TPS 可以达到几千的级别,并且每次堆积的时候在日志层面都有一些“断开连接” 的错误。

所以从日志层面分析,肯定是消费线程出了问题,导致消费能力下降从而堆积,从而问题就转变为为什么线程会出现异常。

仔细查了下应用层面的监控,发现应用有频繁的 FullGC 发生,奇怪的是为什么频繁 FullGc 却没有触发报警呢?看了一眼简直要吐血,因为 FullGc 的报警开关被关了。。。

至此基本上能知道问题的原因了,因为发生了 FullGc 导致 STW,然后消费线程挂了,导致消息堆积,重启后内存释放重新进行消费。接下来的问题就转变为排查 FullGc 的原因了。

排查 FullGc 的基本流程首先肯定是 dump 一下内存的 heap ,然后分析一下内存泄露的代码块。通过 dump 下来的日志,发现在代码中使用 ThreadLocal,但是没有释放,从而导致频次的 FullGc。问题到这基本上也解决了,修改了相关的地方,重新上线,稳定运行。

至此没有堆积,没有报警,没有重启,爽歪歪!

总结

敬畏线上,不要放过任何一个线上的异常和报警!

有时候问题的表象并不是真正的原因,我们需要精准的找到根源,解决问题最难的地方是找到问题!

别干随便关闭线上监控报警的事情!

另外之所以能快速的定位到问题所在也是因为系统有着很好的异常监控,可以监测到慢 SQL 和堆积报警,这也告诉我们平时的服务监控是很重要的。

前端项目

之前有个内部服务,在部署服务的时候,Nginx 配置了 http 和 https 两个 server,公司内部使用的时候一直都用的是 https,结果今天运营同事突然说访问不了了,通过观察发现是 http 协议访问不通。

正常的逻辑是如果用户在地址栏直接输入 xxx.com 的时候默认是走的 http 协议 80 端口,在 nginx 层会转发到 https 的 443 端口,也就是会有一个重定向的过程。

检查了一下 nginx 的配置文件,发现在 80 这个 server 里面没有配置 server_name,修改如下就好了。

只能说太粗心了

server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  xxx.com www.xxx.com;
        root         /usr/share/nginx/html;
    return 301 https://$server_name$request_uri;
    }
    
 server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  xxx.com www.xxx.com;
        root         /usr/share/nginx/html;

        ssl_certificate "xxx.crt";
        ssl_certificate_key "xxx.key";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers PROFILE=SYSTEM;
        ssl_prefer_server_ciphers on;
        location / {
        proxy_pass http://backend$request_uri;
            proxy_set_header  Host $host:$server_port;
            proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            client_max_body_size  10m;
            # 实现前端打字效果
        proxy_buffering off;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

页面加载时间优化

另外在使用的时候还发现,有的时候网页或者手机打开网站需要好几秒才能把整个页面渲染出来,自己用起来都很不爽更别说什么用户体验了。

通过浏览器的 .NETwork 栏目,发现网站在加载的时候会联网访问一个 css 文件,这个 css 文件里面会用到很多字体文件,而且这些字体文件也是从网络实时下载的。

看了下 Issue 发现也有其他人遇到了这个问题,这个更夸张直接加载了 42 秒。

图片图片

通过将这个问题提交下载下来,然后直接访问,不再从网络上下载。手动将这个 css 文件下载下来过后,发现里面还引用的很多字体文件,如下所示,总共 388 个,这样是手动一个个下载那不是要了老命。

图片图片

所以需要通过脚本来进行下载,通过询问 ChatGPT 让它帮我们写一个 go 语言脚本来执行这个逻辑。

图片图片

完整的代码如下所示

package mAIn

import (
 "bufio"
 "fmt"
 "net/http"
 "os"
 "regexp"
 "strings"
)

func main() {
 const cssPath = "css2.css"
 const fontDir = "fonts"
 const urlPrefix = "https:"

 // 读取 CSS 文件
 cssFile, err := os.Open(cssPath)
 if err != nil {
  panic(fmt.Sprintf("Failed to open %s: %s", cssPath, err))
 }
 defer cssFile.Close()

 // 创建字体存储目录
 if err := os.MkdirAll(fontDir, 0755); err != nil {
  panic(fmt.Sprintf("Failed to create font directory: %s", err))
 }

 // 解析 CSS 文件
 scanner := bufio.NewScanner(cssFile)
 for scanner.Scan() {
  line := scanner.Text()
  if strings.Contains(line, "url(") && strings.Contains(line, ".woff2") {
   // 使用正则表达式提取 WOFF2 文件 URL
   re := regexp.MustCompile(`url(["']?([^"']+.(woff2))`)
   matches := re.FindStringSubmatch(line)

   if len(matches) >= 2 {
    fontUrl := matches[1]
    if strings.HasPrefix(fontUrl, "//") {
     fontUrl = urlPrefix + fontUrl
    }

    // 下载 WOFF2 文件
    fmt.Printf("Downloading %s...n", fontUrl)
    res, err := http.Get(fontUrl)
    if err != nil {
     fmt.Printf("Failed to download %s: %sn", fontUrl, err)
     continue
    }
    defer res.Body.Close()
     // 创建字体文件
    fontPath := fmt.Sprintf("%s/%s", fontDir, matches2)
    fontFile, err := os.Create(fontPath)
    if err != nil {
     fmt.Printf("Failed to create font file %s: %sn", fontPath, err)
     continue
    }
    defer fontFile.Close()

    // 写入字体文件
    _, err = fontFile.ReadFrom(res.Body)
    if err != nil {
     fmt.Printf("Failed to write to font file %s: %sn", fontPath, err)
    } else {
     fmt.Printf("Font file %s downloaded.n", fontPath)
    }
   }
  }
 }
}

ChatGPT 不仅给出了代码,还给出了解释

此脚本遵循以下步骤:

  1. 打开 CSS 文件
  2. 逐行读取文件内容
  3. 对每一行使用正则表达式进行匹配,查找字体文件链接
  4. 使用 http.Get() 发送 HTTP 请求下载字体文件
  5. 创建本地文件,并将字体数据写入该文件

图片图片

上面代码通过 go run download.go 直接运行脚本发现是可以正常运行的,但是一开始是有个问题的那就是没有考虑到多个文件会覆盖,我们简单修改几行就可以正常使用了。

index := strings.LastIndex(matches[1], "/")
filename := matches[1][index+1:]
// 创建字体文件
fontPath := fmt.Sprintf("%s/%s", fontDir, filename)

运行后的效果是这样的,全部下载下来,我们需要做的就是在 css 文件中通过快捷键全部替换一下就好了。

图片图片

优化过后文件的下载速度稳定了一秒以内,虽然还可以通过 CDN 等方式进一步优化,但是感觉目前是没必要的。现在剩下的就是受限于服务器的宽带和网络了,不过整体是可以接受的了。

图片图片

试了下移动端打开的速度也有所提升。

总结

通过上面的过程,可以看到 ChatGPT 是真的可以帮我们提高工作效率的,写一个脚本没什么难度,花点时间也是可以写出来的,但是有了这样的工具大大的节省了我们的时间,对于生成的内容需要能看懂和能进行修改就行了。

但是工具也只是工具,还是要学会使用才行,不能太盲目的依赖。



Tags:程序员   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
AI程序员上岗 垂类大模型应用迎来井喷期
能自动写代码的“AI员工”、逐渐告别不够好用的智能客服,无需费时费力开发的工业AI控制器……随着人工智能大模型能力开始深入多个行业,IT、工业生产、金融、服务...【详细内容】
2024-04-07  Search: 程序员  点击:(3)  评论:(0)  加入收藏
首个AI程序员上岗,码农们暂且不必过度焦虑
“AI程序员上岗”或许是噱头,但淘汰焦虑仍然近在咫尺,需要积极面对。全文2418字,阅读约需7分钟 撰稿 / 马尔文(媒体人)编辑 / 何睿 校对 / 张彦君▲随着相关技术的突飞猛进,AI也在...【详细内容】
2024-04-07  Search: 程序员  点击:(5)  评论:(0)  加入收藏
被“摧毁”的数藏玩家:父母50万积蓄变电子垃圾,31岁程序员送外卖还网贷
最窘迫的时候,张晖把借款软件和信用卡都借了个遍,支付宝借呗16万的额度,他也全部用光了。真正压倒张晖的 ,还有一个他难以启齿的“秘密”:一年之内,父母50万的积蓄全部变成了数字...【详细内容】
2024-03-27  Search: 程序员  点击:(15)  评论:(0)  加入收藏
AI程序员Devin:通过了面试,但不一定适合职场
昨天,AI圈上演了第一场“大男主爽文”:一个少年成名的编程天才,组建起仅有10人的编程界奥林匹克“梦之队”,在全球瞩目的科技风暴正中心创办了一家公司。成立不到两个月,其推出的...【详细内容】
2024-03-18  Search: 程序员  点击:(13)  评论:(0)  加入收藏
微软AI程序员登场,10倍AI工程师真来了?996自主生成代码,性能超GPT-4 30%
新智元报道编辑:桃子 润【新智元导读】全球首个AI程序员Devin诞生之后,让码农纷纷恐慌。没想到,微软同时也整出了一个AI程序员——AutoDev,能够自主生成、执行代码等...【详细内容】
2024-03-18  Search: 程序员  点击:(15)  评论:(0)  加入收藏
全球首位AI程序员诞生 人类程序员会失业吗?
近日,世界上第一位AI程序员Devin诞生,号称能自主学习新技术,自己改Bug,甚至它已经成功通过一家AI公司面试。消息一出,震撼整个科技圈。不少从业者在社交媒体留言说,担心Devin这类A...【详细内容】
2024-03-17  Search: 程序员  点击:(24)  评论:(0)  加入收藏
李彦宏称程序员职业将不复存在,周鸿祎:程序员热十年内不会减弱,AI时代更需要程序员
李彦宏称程序员职业将不复存在,周鸿祎:程序员热十年内不会减弱,AI时代更需要程序员3月10日,360创始人周鸿祎在社交平台上发文称,“大模型将替代程序员?未来不用学编程了么?我认为,程...【详细内容】
2024-03-11  Search: 程序员  点击:(21)  评论:(0)  加入收藏
李彦宏最新发声,“程序员”职业将不复存在!
在3月9日央视的《对话》·开年说节目上,百度创始人、董事长兼CEO李彦宏表示,以后不会存在“程序员”这种职业了,因为只要会说话,人人都会具备程序员的能力。“未来的编程...【详细内容】
2024-03-11  Search: 程序员  点击:(18)  评论:(0)  加入收藏
编程二十年,38岁谷歌程序员的16条建议,涉创业、技术淘汰、拿大厂offer……
以能够让项目自负盈亏,并在这一约束下优化其增长的方式来管理和调整项目,这是这个世上最厉害的本事。距离我正式开始编程的工作已经过去二十年了。在这些年里,我有以下收获: 获...【详细内容】
2024-03-10  Search: 程序员  点击:(4)  评论:(0)  加入收藏
有了LLM,所有程序员都将转变为架构师?
编译 | 言征 出品 | 51CTO技术栈(微信号:blog51cto)生成式人工智能是否会取代人类程序员?可能不会。但使用生成式人工智能的人类可能会,可惜的是,现在还不是时候。目前,我们正在见...【详细内容】
2024-03-07  Search: 程序员  点击:(19)  评论:(0)  加入收藏
▌简易百科推荐
AI程序员上岗 垂类大模型应用迎来井喷期
能自动写代码的“AI员工”、逐渐告别不够好用的智能客服,无需费时费力开发的工业AI控制器……随着人工智能大模型能力开始深入多个行业,IT、工业生产、金融、服务...【详细内容】
2024-04-07    千龙网  Tags:AI程序员   点击:(3)  评论:(0)  加入收藏
首个AI程序员上岗,码农们暂且不必过度焦虑
“AI程序员上岗”或许是噱头,但淘汰焦虑仍然近在咫尺,需要积极面对。全文2418字,阅读约需7分钟 撰稿 / 马尔文(媒体人)编辑 / 何睿 校对 / 张彦君▲随着相关技术的突飞猛进,AI也在...【详细内容】
2024-04-07    新京报  Tags:AI程序员   点击:(5)  评论:(0)  加入收藏
为何大语言模型不会取代码农?
译者 | 布加迪审校 | 重楼生成式人工智能(GenAI)会取代人类程序员吗?恐怕不会。不过,使用GenAI的人类可能会取代程序员。但是如今有这么多的大语言模型(LLM),实际效果不一而足。如...【详细内容】
2024-03-21    51CTO  Tags:大语言模型   点击:(21)  评论:(0)  加入收藏
AI程序员Devin:通过了面试,但不一定适合职场
昨天,AI圈上演了第一场“大男主爽文”:一个少年成名的编程天才,组建起仅有10人的编程界奥林匹克“梦之队”,在全球瞩目的科技风暴正中心创办了一家公司。成立不到两个月,其推出的...【详细内容】
2024-03-18    甲子光年  Tags:AI程序员   点击:(13)  评论:(0)  加入收藏
微软AI程序员登场,10倍AI工程师真来了?996自主生成代码,性能超GPT-4 30%
新智元报道编辑:桃子 润【新智元导读】全球首个AI程序员Devin诞生之后,让码农纷纷恐慌。没想到,微软同时也整出了一个AI程序员——AutoDev,能够自主生成、执行代码等...【详细内容】
2024-03-18    新智元  Tags:AI程序员   点击:(15)  评论:(0)  加入收藏
李彦宏称程序员职业将不复存在,周鸿祎:程序员热十年内不会减弱,AI时代更需要程序员
李彦宏称程序员职业将不复存在,周鸿祎:程序员热十年内不会减弱,AI时代更需要程序员3月10日,360创始人周鸿祎在社交平台上发文称,“大模型将替代程序员?未来不用学编程了么?我认为,程...【详细内容】
2024-03-11    九派新闻  Tags:程序员   点击:(21)  评论:(0)  加入收藏
李彦宏最新发声,“程序员”职业将不复存在!
在3月9日央视的《对话》·开年说节目上,百度创始人、董事长兼CEO李彦宏表示,以后不会存在“程序员”这种职业了,因为只要会说话,人人都会具备程序员的能力。“未来的编程...【详细内容】
2024-03-11    红星新闻  Tags:程序员   点击:(18)  评论:(0)  加入收藏
编程二十年,38岁谷歌程序员的16条建议,涉创业、技术淘汰、拿大厂offer……
以能够让项目自负盈亏,并在这一约束下优化其增长的方式来管理和调整项目,这是这个世上最厉害的本事。距离我正式开始编程的工作已经过去二十年了。在这些年里,我有以下收获: 获...【详细内容】
2024-03-10    CSDN  Tags:程序员   点击:(4)  评论:(0)  加入收藏
鸿蒙开发岗平均月薪超1.8万,成为计算机人才和程序员的求职新选择!
智联招聘发布的《2024年春招市场行情周报(第一期)》显示,2023年9-12月,鸿蒙相关职位数同比增速从33.8%攀升至216.1%,鸿蒙相关职位的投递人数同比增速从132.1%攀升至380.1%。春节...【详细内容】
2024-02-26  晓枫侃科技    Tags:鸿蒙开发   点击:(25)  评论:(0)  加入收藏
AI最先砸了程序员饭碗?90%码农认为找工作变难,大学生也要调整职业规划
图片来源:由无界 AI生成想不到AI最先影响到的打工人,居然是程序员。最近外媒一个有超过1万程序员参与的职业调查显示,90%的程序员都认为现在找工作变得更难了。仿佛一夜之间,程...【详细内容】
2024-01-12    新智元  Tags:程序员   点击:(78)  评论:(0)  加入收藏
站内最新
站内热门
站内头条