waouooo

waouooo:一个很哇塞的博客

重生2024,重启waouooo IT技术公众号&站点博客计划。。。

2023年大概会覆盖一下几点内容,(按时间以及紧急程度排序)

  1. 面试系列
  2. JVM相关知识梳理
  3. 设计模式
  4. golang实现基础的一些数据结构(使用泛型)
  5. 领域驱动设计(DDD)
  6. DDIA读书笔记
  7. 数据库相关内容
  8. 其他技术相关记录

2024年计划

  1. 能发几篇是几篇

waouooo长期打算

希望可以打造一个很哇塞的技术站点(当然也可以不仅限于技术),记录一些日常积累学习的东西,做一些有意思的小玩意儿,往头发越来越少的道路上一路高歌猛进。

欢迎关注公众号:

Subsections of waouooo

Chapter 1

Golang

Golang

golang 相关内容

Subsections of Golang

time.Tick() 内存泄漏问题排查

背景:

目前我们开发的流水线服务(pipeline)任务状态流转主要依赖drone-server往pipeline中推送,推送过程涉及drone-server -> webhook , webhook -> pipeline 两个过程,因为网络不完全可靠,因此会出现偶尔的状态丢失问题。现在通过pipeline 中定时向drone-server中查询build状态来弥补部分状态丢失问题。当任务开发完成投入预发环境运行时,观察监控发现: pipeline服务长时间运行后会出现cpu和内存缓慢增长的问题。

监控图表📈:

cpu: cpu cpu mem: mem mem

问题排查

  1. 使用pprof 观察
pipeline  go tool pprof https://xxx.com/debug/pprof/heap
Fetching profile over HTTP from https://xxx.com/debug/pprof/heap
Saved profile in /Users/zhou/pprof/pprof.pipeline.alloc_objects.alloc_space.inuse_objects.inuse_space.001.pb.gz
File: pipeline
Build ID: f5b549d19b3a22503c2410c78834ba394de7cfa6
Type: inuse_space
Time: Nov 22, 2022 at 9:11am (CST)
Entering interactive mode (type "help" for commands, "o" for options) 
(pprof) top
Showing nodes accounting for 17358.76kB, 91.86% of 18897kB total
Showing top 10 nodes out of 125
      flat  flat%   sum%        cum   cum%
 8192.69kB 43.35% 43.35%  8192.69kB 43.35%  time.NewTicker
 2802.47kB 14.83% 58.18%  2802.47kB 14.83% ******/pipeline/vendor/github.com/klauspost/compress/zstd.encoderOptions.encoder
 1805.17kB  9.55% 67.74%  1805.17kB  9.55%  compress/flate.NewWriter
 1025.80kB  5.43% 73.17%  1543.13kB  8.17%  ******/pipeline/vendor/google.golang.org/protobuf/internal/filedesc.(*Message).unmarshalFull
  768.26kB  4.07% 77.23%   768.26kB  4.07%  syscall.copyenv
  613.99kB  3.25% 80.48%   613.99kB  3.25%  bytes.makeSlice
  578.66kB  3.06% 83.54%   578.66kB  3.06%  ******/pipeline/vendor/github.com/klauspost/compress/zstd.(*blockEnc).init
  536.37kB  2.84% 86.38%   536.37kB  2.84%  regexp/syntax.(*compiler).inst
  518.02kB  2.74% 89.12%   518.02kB  2.74%  ******/pipeline/vendor/github.com/beorn7/perks/quantile.newStream
  517.33kB  2.74% 91.86%   517.33kB  2.74%  ******/pipeline/vendor/google.golang.org/protobuf/internal/strs.(*Builder).AppendFullName
(pprof) web
pipeline  go tool pprof https://xxx.com/debug/pprof/profile\?second\=120
Fetching profile over HTTP from https://xxx.com/debug/pprof/profile?second=120
Saved profile in /Users/zhou/pprof/pprof.pipeline.samples.cpu.001.pb.gz
File: pipeline
Build ID: f5b549d19b3a22503c2410c78834ba394de7cfa6
Type: cpu
Time: Nov 22, 2022 at 9:15am (CST)
Duration: 30.10s, Total samples = 1.18s ( 3.92%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 1.13s, 95.76% of 1.18s total
Showing top 10 nodes out of 28
      flat  flat%   sum%        cum   cum%
     0.66s 55.93% 55.93%      0.66s 55.93%  runtime.siftdownTimer
     0.13s 11.02% 66.95%      0.13s 11.02%  runtime.epollwait
     0.12s 10.17% 77.12%      0.13s 11.02%  runtime.chansend
     0.05s  4.24% 81.36%      0.07s  5.93%  runtime.nanotime (inline)
     0.05s  4.24% 85.59%      0.05s  4.24%  runtime.walltime (inline)
     0.04s  3.39% 88.98%      1.18s   100%  runtime.findrunnable
     0.03s  2.54% 91.53%      0.03s  2.54%  runtime.unlock2
     0.02s  1.69% 93.22%      0.02s  1.69%  runtime.nanotime1
     0.02s  1.69% 94.92%      0.15s 12.71%  runtime.netpoll
     0.01s  0.85% 95.76%      0.01s  0.85%  runtime.(*randomEnum).done (inline)
(pprof) web
  1. 使用web命令生成svg图片观察更直观: heap heap

cpu cpu

heap svg cpu svg

  1. 通过pprof分析可得cpu与heap主要被runtime包中的方法占用了。 其实从heap的性能图中基本可以看出主要是被time.NewTicker给占用了,而新增的代码中只有一处使用了tick进行计时,代码如下:
util.Go(func() {  
   func(r *RM, ch chan int) {  
      for {  
         select {  
         case <-time.Tick(time.Second):  
            second := time.Now().Second()  
            r.RLock()  
            existed := r.m[second]  
            r.RUnlock()  
            if !existed {  
               util.Go(func() {  
                  t.readCache(second, ch)  
               })  
            }  
            r.Lock()  
            r.m[second] = true  
            r.Unlock()  
         }  
      }  
   }(r, ch)  
})
  1. 进入time.Tick方法查看源码如下:
// Tick is a convenience wrapper for NewTicker providing access to the ticking
// channel only. While Tick is useful for clients that have no need to shut down
// the Ticker, be aware that without a way to shut it down the underlying  
// Ticker cannot be recovered by the garbage collector; it "leaks".
// Unlike NewTicker, Tick will return nil if d <= 0.
func Tick(d Duration) <-chan Time {  
   if d <= 0 {  
      return nil  
   }  
   return NewTicker(d).C  
}

通过代码以及其注释可知,每调用一次Tick() 方法都会生成一个新的Ticker,并且没有办法被关闭,从而无法被gc回收导致内存泄漏。而在业务代码中,在循环调用time.Tick()方法进行倒计时,导致生成了大量的Ticker在内存中,使得应用资源使用率在不断得增加。

  1. 代码修改:
util.Go(func() {  
   func(r *RM, ch chan int) {  
      // 在循环开始前初始化一个ticker
      ticker := time.NewTicker(time.Second)  
      for {  
         select {  
         case <-ticker.C:  
            second := time.Now().Second()  
            r.RLock()  
            existed := r.m[second]  
            r.RUnlock()  
            if !existed {  
               util.Go(func() {  
                  t.readCache(second, ch)  
               })  
            }  
            r.Lock()  
            r.m[second] = true  
            r.Unlock()  
         }  
      }  
   }(r, ch)  
})
在循环开始之前生成唯一一个ticker,从而避免使用time.Tick()的包装方法每次都生成新的ticker,因为这个倒计时存在于整个应用运行的生命周期,因此也无需关闭
  1. 修复后的监控图表📈:

cpu: cpu cpu

mem: mem mem

Chapter 2

Java

Java

java 相关内容

Subsections of Java

使用IDEA2023快速创建Spring Boot项目

方式一:通过空项目创建

点击IDEA然后点击New Project 按下图内容填入自己需要的值点击Create即可

方式二:通过spring Initializr创建

Arthas使用指南

背景

通常我们在开发过程中通常会使用debug功能来对代码进行调试,以此来解决响应的一些问题。但是在生成环境中程序出现了异常,我们无法使用IDE的调试功能,即便有远程调试,在生产环境中也是不可接受的,因为调试的过程中会暂停所有线程,导致服务暂停。这时我们就需要通过其他手段来对问题进行追踪调试,而Arthas可以很好的完成这些能力。

Arthas 是Alibaba开源的一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率,支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。以下是官方列举的一些开发人员遇到问题时可以使用Arthas解决的场景:

1.  这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
2.  我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
3.  遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
4.  线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
5.  是否有一个全局视角来查看系统的运行状况?
6.  有什么办法可以监控到 JVM 的实时运行状态?
7.  怎么快速定位应用的热点,生成火焰图?
8.  怎样直接从 JVM 内查找某个类的实例?

Arthas相关链接:

快速入门

Chapter 3

Linux

Linux

linux 相关内容

Subsections of Linux

Chapter 4

算法

算法

算法记录

graph TD
A[根节点]-->B[子节点1]
A-->C[子节点2]
A-->D[子节点3]
B-->E[1]
B-->F[2]
B-->G[3]
Chapter 0

快速建站

快速建站

使用Hugo + Github Pages + Giscus 进行个人博客站点搭建

Subsections of 快速建站

Hugo+Github Pages快速搭建个人博客一:基础建站

需求:创建一个个人博客

对程序员来说个人博客是一个非常常见的东西,可以在上面记录自己的学习积累,同时也可以通过互联网分享给大家。个人博客建站的方式有很多,本文不做横向比较,本着白嫖与图方便并兼顾可用性强的角度,选择使用Hugo + Github Pages + Giscus 进行建站。

工具简介:

Hugo

Hugo 是一个golang编写的静态网站生成器,可以从markdown格式生成。

Github Pages

Github Pages 是Github提供的静态站点托管服务,可以通过仓库(repository)的形式托管静态网站,同类型的还有国内的Gitee Pages

Giscus

Giscus 是一个站点评论系统,基于Github的Discussions功能

创建Github Pages

  1. 登录github 创建一个<username>.github.io的仓库 创建仓库 创建仓库
  2. 使用<username>.github.io  作为存储库名称。 将 username 替换为你的 GitHub 用户名。 例如,如果用户名为 waouooo,则存储库名称应为 waouooo.github.io (ps: 为了保证Github Pages 的可见性,普通用户需要将仓库设置为public,若想使用private,也可以氪金)
  3. 点击Settings配置Github Pages
  4. 查看Github Pages 配置
  5. 返回仓库主页查看部署状态:若出现绿色的勾勾✅则表示部署完成,可以通过访问https://waouooo.github.io 来查看,若是其他标志,也可以点击查看具体的工作流流程。

使用Hugo 初始化站点

  1. macOS安装hugo, 其他操作系统安装方式可以参考官方文档
brew install hugo
  1. 安装完成后查看当前安装的版本
hugo version
# 输出: hugo v0.105.0+extended darwin/amd64 BuildDate=unknown
  1. 初始化站点
hugo new site waouooo
Congratulations! Your new Hugo site is created in /Users/waouooo/Workspace/waouooo.

Just a few more steps and you're ready to go:

1. Download a theme into the same-named folder.
   Choose a theme from https://themes.gohugo.io/ or
   create your own with the "hugo new theme <THEMENAME>" command.
2. Perhaps you want to add some content. You can add single files
   with "hugo new <SECTIONNAME>/<FILENAME>.<FORMAT>".
3. Start the built-in live server via "hugo server".

Visit https://gohugo.io/ for quickstart guide and full documentation.
  1. 进入站点目录并以git submodule模式添加主题,本站点使用主题为hugo-theme-relearn(官方文档), 其他主题可进入官网主题 选择
cd waouooo
# 使用git 初始化仓库
git init
# 输出: 已初始化空的 Git 仓库于 /Users/zhou/Workspace/waouooo/waouooo/.git/
git submodule add https://github.com/McShelby/hugo-theme-relearn.git themes/hugo-theme-relearn
  1. 从主题exampleSite目录中拷贝配置
cp themes/hugo-theme-relearn/exampleSite/config.toml .
  1. 修改配置文件baseURL与:themesdir
# this is a required setting for this theme to appear on https://themes.gohugo.io/
# change this to a value appropriate for you; if your site is served from a subdirectory
# set it like "https://example.com/mysite/"
# 修改此处✅
baseURL = "https://waouooo.github.io/"

# canonicalization will only be used for the sitemap.xml and index.xml files;
# if set to false, a site served from a subdirectory will generate wrong links
# inside of the above mentioned files; if you serve the page from the servers root
# you are free to set the value to false as recommended by the official Hugo documentation
canonifyURLs = true # true -> all relative URLs would instead be canonicalized using baseURL
# required value to serve this page from a webserver AND the file system;
# if you don't want to serve your page from the file system, you can also set this value
# to false
relativeURLs = true # true -> rewrite all relative URLs to be relative to the current content
# if you set uglyURLs to false, this theme will append 'index.html' to any branch bundle link
# so your page can be also served from the file system; if you don't want that,
# set disableExplicitIndexURLs=true in the [params] section
uglyURLs = false     # true -> basic/index.html -> basic.html

# the directory where Hugo reads the themes from; this is specific to your
# installation and most certainly needs be deleted or changed
# 修改此处✅
themesdir = "./themes"
# yeah, well, obviously a mandatory setting for your site, if you want to
# use this theme ;-)
theme = "hugo-theme-relearn"

# the main language of this site; also an automatic pirrrate translation is
# available in this showcase
languageCode = "en"
# make sure your defaultContentLanguage is the first one in the [Languages]
# array below, as the theme needs to make assumptions on it
defaultContentLanguage = "en"
# if you want to get rrrid o' ourrr pirrrates nonsense uncomment th' next line
# disableLanguages = ['pir']

# the site's title of this showcase; you should change this ;-)
title = "Hugo Relearn Documentation"

# We disable this for testing the exampleSite; you must do so too
# if you want to use the themes parameter disableGeneratorVersion=true;
# otherwise Hugo will create a generator tag on your home page
disableHugoGeneratorInject = true

[outputs]
  # add JSON to the home to support lunr search; This is a mandatory setting
  # for the search functionality
  # add PRINT to home, section and page to activate the feature to print whole
  # chapters
  home = ["HTML", "RSS", "PRINT", "SEARCH", "SEARCHPAGE"]
  section = ["HTML", "RSS", "PRINT"]
  page = ["HTML", "RSS", "PRINT"]

[markup]
  [markup.highlight]
    # if `guessSyntax = true`, there will be no unstyled code even if no language
    # was given BUT Mermaid and Math codefences will not work anymore! So this is a
    # mandatory setting for your site if you want to use Mermaid or Math codefences
    guessSyntax = false

    # here in this showcase we use our own modified chroma syntax highlightning style
    # which is imported in theme-relearn-light.css / theme-relearn-dark.css;
    # if you want to use a predefined style instead:
    # - remove the following `noClasses`
    # - set the following `style` to a predefined style name
    # - remove the `@import` of the self-defined chroma stylesheet from your CSS files
    #   (here eg.: theme-relearn-light.css / theme-relearn-dark.css)
    noClasses = false
    # style = "tango"

  [markup.goldmark.renderer]
    # activated for this showcase to use HTML and JavaScript; decide on your own needs;
    # if in doubt, remove this line
    unsafe = true

# allows `hugo server` to display this showcase in IE11; this is used for testing, as we
# are still supporting IE11 - although with degraded experience; if you don't care about
# `hugo server` or browsers of ancient times, fell free to remove this whole block
[server]
  [[server.headers]]
    for = "**.html"
    [server.headers.values]
       X-UA-Compatible = "IE=edge"

# showcase of the menu shortcuts; you can use relative URLs linking
# to your content or use fully-quallified URLs to link outside of
# your project
[Languages]
  [Languages.en]
    title = "Hugo Relearn Theme"
    weight = 1
    languageName = "English"
    landingPageName = "<i class='fas fa-home'></i> Home"

  [[Languages.en.menu.shortcuts]]
    name = "<i class='fab fa-fw fa-github'></i> GitHub repo"
    identifier = "ds"
    url = "https://github.com/McShelby/hugo-theme-relearn"
    weight = 10

  [[Languages.en.menu.shortcuts]]
    name = "<i class='fas fa-fw fa-camera'></i> Showcases"
    url = "more/showcase/"
    weight = 11

  [[Languages.en.menu.shortcuts]]
    name = "<i class='fas fa-fw fa-bookmark'></i> Hugo Documentation"
    identifier = "hugodoc"
    url = "https://gohugo.io/"
    weight = 20

  [[Languages.en.menu.shortcuts]]
    name = "<i class='fas fa-fw fa-bullhorn'></i> Credits"
    url = "more/credits/"
    weight = 30

  [[Languages.en.menu.shortcuts]]
    name = "<i class='fas fa-fw fa-tags'></i> Tags"
    url = "tags/"
    weight = 40

  # this is ourrr way t' showcase th' multilang settings by
  # doing autotrrranlat'n of th' english content; we are
  # lazy and don't supporrt furrrther trrranslations; arrr,
  # don't take it t' serrrious, fello'; it's prrretty hacky and:
  # NOT MEANT FER PRRRODUCTION! ARRR!

  [Languages.pir]
    title = "Cap'n Hugo Relearrrn Theme"
    weight = 2
    languageName = "Arrr! ☠ Pirrrates ☠"
    landingPageName = "<i class='fas fa-home'></i> Arrr! Home"

  [[Languages.pir.menu.shortcuts]]
    name = "<i class='fab fa-fw fa-github'></i> GitHub repo"
    identifier = "ds"
    url = "https://github.com/McShelby/hugo-theme-relearn"
    weight = 10

  [[Languages.pir.menu.shortcuts]]
    name = "<i class='fas fa-fw fa-camera'></i> Showcases"
    url = "more/showcase/"
    weight = 11

  [[Languages.pir.menu.shortcuts]]
    name = "<i class='fas fa-fw fa-bookmark'></i> Cap'n Hugo Documentat'n"
    identifier = "hugodoc"
    url = "https://gohugo.io/"
    weight = 20

  [[Languages.pir.menu.shortcuts]]
    name = "<i class='fas fa-fw fa-bullhorn'></i> Crrredits"
    url = "more/credits/"
    weight = 30

  [[Languages.pir.menu.shortcuts]]
    name = "<i class='fas fa-fw fa-tags'></i> Arrr! Tags"
    url = "tags/"
    weight = 40

# mounts are only needed in this showcase to access the publicly available screenshots;
# remove this section if you don't need further mounts
[module]
  [[module.mounts]]
    source = 'archetypes'
    target = 'archetypes'
  [[module.mounts]]
    source = 'assets'
    target = 'assets'
  [[module.mounts]]
    source = 'content'
    target = 'content'
  [[module.mounts]]
    source = 'data'
    target = 'data'
  [[module.mounts]]
    source = 'i18n'
    target = 'i18n'
  [[module.mounts]]
    source = '../images'
    target = 'content/images'
  [[module.mounts]]
    source = 'layouts'
    target = 'layouts'
  [[module.mounts]]
    source = 'static'
    target = 'static'

# settings specific to this theme's features; choose to your likings and
# consult this documentation for explaination
# 修改此处✅ 按需修改
[params]
  editURL = "https://github.com/waouooo//edit/main/exampleSite/content/"
  description = "waouooo: 一个很哇塞的博客"
  author = "waouooo"
  showVisitedLinks = true
  collapsibleMenu = true
  disableBreadcrumb = false
  disableInlineCopyToClipBoard = true
  disableNextPrev = false
  disableLandingPageButton = true
  titleSeparator = "::"
  themeVariant = [ "relearn-light", "relearn-dark", "learn", "neon", "blue", "green", "red" ]
  disableSeoHiddenPages = true
  # this is for the stylesheet generator to allow for interactivity in Mermaid
  # graphs; you usually will not need it and you should remove this for
  # security reasons
  mermaidInitialize = "{ \"securityLevel\": \"loose\" }"
  additionalContentLanguage = [ "en" ]
  1. 添加主页文章内容 创建文章draft默认为true,修改为false可以展示出来
hugo new _index.md
# 输出:Content "/Users/waouooo/Workspace/waouooo/content/_index.md" created
vim /Users/waouooo/Workspace/waouooo/content/_index.md

---
title: "waouooo"
date: 2023-01-28T23:30:32+08:00
draft: false
---

### waouooo::一个很哇塞的博客
  1. 启动博客并访问地址查看
hugo serve
port 1313 already in use, attempting to use an available port
Start building sites …
hugo v0.105.0+extended darwin/amd64 BuildDate=unknown

                   | EN  | PIR
-------------------+-----+------
  Pages            |  10 |  10
  Paginator pages  |   0 |   0
  Non-page files   |   0 |   0
  Static files     | 191 | 191
  Processed images |   0 |   0
  Aliases          |   1 |   0
  Sitemaps         |   2 |   1
  Cleaned          |   0 |   0

Built in 177 ms
Watching for changes in /Users/waouooo/Workspace/waouooo/{archetypes,content,data,layouts,static,themes}
Watching for config changes in /Users/waouooo/Workspace/waouooo/config.toml, /Users/waouooo/Workspace/waouooo/themes/hugo-theme-relearn/config.toml
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:64363/ (bind address 127.0.0.1)
Press Ctrl+C to stop
  1. 添加章节或者文章 详细内容可参考relearn官网配置
# 添加章节
hugo new --kind chapter basics/_index.md

# 创建文章内容
hugo new basics/first-content.md
hugo new basics/second-content/_index.md
  1. 以git submodule形式添加github pages托管的仓库, (使用ssh协议方便推送)
git submodule add git@github.com:waouooo/waouooo.github.io.git dist
  1. 生成静态文件 hugo 命令默认将静态文件生成至public目录当中,我们可以通过-d指定生成的目录
hugo -d dist
  1. 推送到github, 等待部署工作流执行完成查看页面
cd dist
git add .
git commit -m "add hugo static pages"

参考链接

1. GitHub Pages 快速入门

2. Hugo Quick Start

Hugo+Github Pages快速搭建个人博客二: 添加giscus评论系统

hugo-theme-relearn 主题添加giscus评论系统

通过上文我们已经实现了博客最重要的发布与展示功能,而作为一个技术博客,如果有一个评论系统供读者进行交流是再好不过了。经过对各个评论系统的横向比较,最终选择的giscus作为评论系统的引擎,那么下面就开始将giscus添加至系统中。

1. 安装giscus

点击https://github.com/apps/giscus访问github中的giscus app安装页面,点击install 安装giscus 安装giscus

选择指定仓库进行安装:

验证github账号密码

至此 waouooo.github.io仓库已安装上giscus

2. 打开Github仓库的Discussions功能

1) giscus是由 GitHub Discussions 驱动的评论系统,因此需要在github上有仓库开启Discussions功能对评论进行托管,我们这里就直接选择博客站点仓库开启Discussions:

2) 在settings的General栏往下拉,找到Features

3) 勾选✅上Discussions

4) 创建一个discussions, 这里选择General作为未来托管评论的category

5) 通过giscus网站生成配置

3. 修改站点目录配置

  1. 在博客站点根目录中创建文件夹
# 创建目录
mkdir -pv layouts/partials
mkdir -pv layouts/_internal
  1. 拷贝主题项目中layouts/partials下的部分文件至占点根目录的layout/partials中,用于添加giscus评论系统的修改
# 拷贝需要的文件
cp themes/hugo-theme-relearn/layouts/partials/content-footer.html layouts/partials
cp themes/hugo-theme-relearn/layouts/partials/custom-comments.html layouts/partials
cp themes/hugo-theme-relearn/layouts/partials/footer.html layouts/partials
cp themes/hugo-theme-relearn/layouts/partials/menu-footer.html layouts/partials
  1. 创建giscus.html文件
touch layout/_internal/giscus.html
  1. 将以下内容拷贝至layout/_internal/giscus.html
<div>
  {{ if site.Params.giscus }}
  <style>
    #comment {
      padding: 8rem 0 2rem;
    }
  
    #comment .vemoji {
        max-width: 1.5em;
        max-height: 1.5em;
    }
  </style>
    <div id="comment">
      <!-- 此处的配置可以直接拷贝2.5)通过giscus网站配置生成的script脚本,也可以将配置值抽取出来,参考下文的方式填入config.toml文件 -->
      <script src="https://giscus.app/client.js"
      data-repo="{{ .Site.Params.giscus.data_repo}}"
      data-repo-id="{{ .Site.Params.giscus.data_repo_id}}"
      data-category="{{ .Site.Params.giscus.data_category}}"
      data-category-id="{{ .Site.Params.giscus.data_category_id}}"
      data-mapping="{{ .Site.Params.giscus.data_mapping}}"
      data-reactions-enabled="{{ .Site.Params.giscus.data_reactions_enabled}}"
      data-emit-metadata="{{ .Site.Params.giscus.data_emit_metadata}}"
      data-input-position="{{ .Site.Params.giscus.data_input_position }}"
      data-theme="{{ .Site.Params.giscus.data_theme}}"
      data-lang="{{ .Site.Params.giscus.data_lang}}"
      crossorigin="{{ .Site.Params.giscus.crossorigin}}"
      data-term="{{ .Site.Params.giscus.data_term }}"
      async>
  </script>
    </div>
    <noscript>Please enable JavaScript to view the comments powered by giscus.</noscript>
  {{ end }}
</div>
  1. 修改layouts/partials/custom-comments.html文件,引入上面修改的giscus.html
<!-- import your comments system
{{ template "_internal/disqus.html" . }}
-->
{{ template "_internal/giscus.html" . }}
  1. 删除layouts/partials/footer.html{{- partial "custom-comments.html" . }} (第3行左右)
  2. layouts/partials/content-footer.html最后追加{{- partial "custom-comments.html" . }}
{{- with .Params.LastModifierDisplayName }}
            <i class='fas fa-user'></i> {{ with $.Params.LastModifierEmail }}<a href="mailto:{{ . }}">{{ end }}{{ . }}{{ with $.Params.LastModifierEmail }}</a>{{ end }}
  {{- with $.Date }}
            <i class='fas fa-calendar'></i> {{ . | time.Format ":date_medium" }}
  {{- end }}
{{- end }}
{{- partial "custom-comments.html" . }}
  1. 自定义layouts/partials/menu-footer.html中的内容,也可不修改
	<style>
		#footer {
		  font-size: 13px;
		  height: 100px;
		  margin-left: auto;
		  margin-right: auto;
		  padding: 2rem 1rem;
		  text-align: center;
		  min-width: 230px;
		  max-width: 300px;
		}
		#footer p {
		  margin: 0;
		}
	  </style>
	  <p>Built with <a href="https://github.com/McShelby/hugo-theme-relearn" title="love"><i class="fas fa-heart"></i></a> by <a href="https://gohugo.io/">Hugo</a></p>
	  <script async="" src="../../js/buttons.js?1674688248"></script>
   

4. 修改config.toml文件

  1. layout/_internal/giscus.html文件中giscus的script脚本参数通过配置提取,则添加以下giscus配置至config.toml 中, data_repo, data_repo_id, data_category data_category_id 这四个参数为上文中开启discussions仓库的数据, data_category使用上文的General。其中的值与上文giscus官网配置得到的值一致
[params.giscus]
  data_repo="waouooo/waouooo.github.io"
  data_repo_id="*****"    
  data_category="General"
  data_category_id="*****"
  data_mapping="pathname"
  data_reactions_enabled="1"
  data_emit_metadata="0"
  data_theme="dark"
  data_lang="zh-CN"
  data_input_position="top"
  data_term="1046"
  crossorigin="anonymous"
  1. 通过GitHub GraphQL API 查询repo_id 和category_id 的内容
{
  resource(url: "https://github.com/waouooo/waouooo.github.io") {
    ... on Repository {
      id
      name
      discussion(number: 1) {
        category {
          id
          name
        }
      }
    }
  }
}

  1. 将查询到的结果回填至config.toml文件的**** 中

5. 重新生成静态页面,上传至仓库中

hugo -d dist
cd dist
git add .
git commit -m "add giscus"
git push

上传成功后等待编译部署完即可查看页面是否成功添加了giscus评论系统了

参考链接

Giscus: The New Commenting Engine for My Website

Hugo Plugin Giscus Support

Hugo+Github Pages快速搭建个人博客三:Github Actions自动部署

前言

通过之前的文章,我们已经把博客站点部署完成,并且添加了giscus评论系统,但是每次发布文章都需要手动执行hugo命令生成站点静态文件,并把文件推送到仓库当中等待部署才能发布。为了简化我们的发布流程,本文将介绍使用Github Actions 来自动构建hugo静态文件,并推送至启用github pages的仓库当中。

1. 创建站点文章仓库

在第一篇中我们只在github上创建了waouooo.github.io仓库,用于保存站点的静态文件,并开启Github Pages。但是我们在使用hugo new site waouooo创建站点文件夹时也对站点文件夹做了git init 操作,因此我们也可以将站点的内容保存至github中。点此创建

2. 关联远程仓库至本地hugo 站点元数据git仓库,并推送

仓库创建完成之后github页面会展示以下内容: 因为我们本地已经有仓库,只需要执行以下内容即可:

git remote add origin git@github.com:waouooo/myblog.git
git push -u origin master

3. 生成sshkey 用于Github Actions推送hugo生成的静态文件至托管仓库

-C 参数指定github用户的邮箱

ssh-keygen -t rsa -C waouooo@163.com
# 以下内容为输出
Generating public/private rsa key pair.
# 此处输入保存新ssh key的文件路径,不要回车,否则使用默认文件名,会被覆盖。其他地方可一路回车
Enter file in which to save the key (/Users/waouooo/.ssh/id_rsa): id_rsa_deploy_key
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa_deploy_key
Your public key has been saved in id_rsa_deploy_key.pub
The key fingerprint is:
SHA256:iKKuSQt+jFiZc3UbeSDY………………tYrvgO+FRI7tSE waouooo@163.com
The key's randomart image is:
+---[RSA 3072]----+
|     o           |
|    . o .        |
|     + . oE o    |
|    o.o.= .= o   |
|  .+.o. S=+.o.   |
| .=.o . . =o+..  |
|+o o     o O.  . |
|*o.o      +.+ .  |
|++.       .oo+   |
+----[SHA256]-----+

以上执行完成之后会在当前目录生成 id_rsa_deploy_key, id_rsa_deploy_key.pub两个文件

4. 将生成的公钥: id_rsa_deploy_key.pub 保存至需要部署的waouooo.github.io项目中

5. 使用ssh私钥: id_rsa_deploy_key 在站点元数据仓库中创建secret

Name建议使用DEPLOY_KEY, 需要下文Github Actions 的Workflow配置文件中使用

6. 创建Github Actions 的工作流(workflow)

将以下内容填充至配置中:

name: GitHub Pages

on:
  push:
    branches:
      - master  # Set a branch to deploy

jobs:
  deploy:
    runs-on: ubuntu-22.04
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: true  # Fetch Hugo themes (true OR recursive)
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: 'latest'
          extended: true

      - name: Build
        run: hugo --minify

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        if: ${{ github.ref == 'refs/heads/master' }}
        with:
         deploy_key: ${{ secrets.DEPLOY_KEY }}  # 上文保存至本仓库secrets中的ssh秘钥变量名
         external_repository: waouooo/waouooo.github.io # 需要将静态文件推送的仓库名
         publish_branch: main # 对应目的仓库的目的分支,因为waouooo主分支为main
         publish_dir: ./public # 推送的文件夹,hugo --minify命令会将静态文件生成至./public文件夹中
         commit_message: ${{ github.event.head_commit.message }} # 指定commit信息

完成后点击start commit完成配置

注意:此时仓库中提交了一个.github/workflows/main.yml的新文件,需要使用git pull 同步至本仓库先,方式下次推送时发生冲突

总结

至此自动化推送已经实现,之后只需要添加文章之后将其推送到远端仓库即可自动触发Github Actions执行自动编译并推送至站点仓库waouooo.github.io中

参考链接

Hugo setup

actions-gh-pages