当前位置: 首页 > news >正文

go原生http开发简易blog(一)项目简介与搭建

文章目录

  • 一、项目简介
  • 二、项目搭建前置知识
  • 三、首页- - -前端文件与后端结构体定义
  • 四、配置文件加载
  • 五、构造假数据- - -显示首页内容

代码地址:https://gitee.com/lymgoforIT/goblog

一、项目简介

使用Go原生http开发一个简易的博客系统,包含一下功能:

  • 文章增删改查,文章列表分页显示
  • 评论系统
  • 文章分类、归档

学习本项目能学到什么?

  • 使用Go开发web项目基本思路,初步具有工程思维,如路由分组、目录组织,代码封装等。
  • 博客基本功能开发套路,如博客与评论的查询、分类、归档、分页等。
  • 循序渐进,掌握编程思维和思路。这一点是最重要的,会不断优化代码,而不是一步给出最终代码,这样更能培养编程思维和思路。

页面效果

在这里插入图片描述

二、项目搭建前置知识

接下来,我们会一步一步实现博客首页,开始我们可能会把代码都写到main.go中,后期再不断调整,优化,形成工程化的目录结构。

首先是启动一个http服务的代码,如下:

package mainimport ("log""net/http"
)func main(){server := http.Server{Addr: "127.0.0.1:8080",}http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {writer.Write([]byte("ok"))})if err := server.ListenAndServe();err != nil {log.Println(err)}
}

启动后,浏览器访问,可以看到ok字样
在这里插入图片描述

这里返回给前端的不过是一个字符串而已,实际工作中一般前后端交互都是使用的JSON数据或者protoc协议的,那么想要返回JSON字符串给前端,又该如何做呢?

其实也简单,设置好请求头即可,如下:

package mainimport ("encoding/json""log""net/http"
)type IndexData struct {Title string `json:"title"`Desc  string `json:"desc"`
}func index(w http.ResponseWriter, r *http.Request) {// 设置请求头,指明返回的是JSON数据w.Header().Set("Content-Type", "application/json")var indexData IndexDataindexData.Title = "go博客"indexData.Desc = "入门学习笔记"jsonStr, _ := json.Marshal(indexData)w.Write(jsonStr)
}func main() {server := http.Server{Addr: "127.0.0.1:8080",}http.HandleFunc("/", index)if err := server.ListenAndServe(); err != nil {log.Println(err)}
}

在这里插入图片描述

目前浏览器得到的响应结果都是后端直接返回的数据,但我们前端是给用户使用的,需要有一定页面才行。

Go中渲染html页面,可以使用Go自带的html/template库,使用方式如下:

首先建立template/index.html文件

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
hello lym blog!!
<br>
标题:{{.Title}}
<br>
描述:{{.Desc}}
</body>
</html>
package mainimport ("encoding/json""fmt""html/template""log""net/http""os"
)type IndexData struct {Title string `json:"title"`Desc  string `json:"desc"`
}func index(w http.ResponseWriter, r *http.Request) {// 设置请求头,指明返回的是JSON数据w.Header().Set("Content-Type", "application/json")var indexData IndexDataindexData.Title = "go博客"indexData.Desc = "入门学习笔记"jsonStr, _ := json.Marshal(indexData)w.Write(jsonStr)
}func indexHtml(w http.ResponseWriter, r *http.Request) {// 使用给定的名字分配一个html模板t := template.New("index.html")viewPath, _ := os.Getwd()// 将html文件关联到模板上t, _ = t.ParseFiles(viewPath + "/template/index.html")var indexData IndexDataindexData.Title = "go博客"indexData.Desc = "入门学习笔记"// 使用给定的数据结构解析模板,并将结果写入werr := t.Execute(w, indexData)fmt.Println(err)
}func main() {server := http.Server{Addr: "127.0.0.1:8080",}http.HandleFunc("/", index)http.HandleFunc("/index", indexHtml)if err := server.ListenAndServe(); err != nil {log.Println(err)}
}

此时访问index路径,便会看到是页面展示了,不过还没有css,js等静态文件渲染,后期会慢慢加上。
在这里插入图片描述

三、首页- - -前端文件与后端结构体定义

有了前面的基础知识,我们现在就可以搭建首页啦!

因为本学习笔记主要注重的是后端逻辑,所以前端页面和静态文件等是直接用的已有的,放到项目目录下即可。如果有需要,可以到码云上取:https://gitee.com/lymgoforIT/goblog

在这里插入图片描述

首页展示时,有很多数据是从后端获取的,所以我们首先需要定义一些结构体,用于数据渲染,其中有一些通用数据,且基本不怎么变的,我们可以放到配置文件中,而不用存DB,比如博客系统的标题、标签以及相关系统变量等。
在这里插入图片描述

config/config.go

package configtype Viewer struct {Title       string   // 首页标题Description string   // 首页描述Logo        string   // 博客系统logoNavigation  []string // 导航栏Bilibili    string   // bilibiliAvatar      string   // 头像UserName    string   // 用户名UserDesc    string   // 用户描述
}// 系统相关配置
type SystemConfig struct {AppName         stringVersion         float32CurrentDir      string // 项目路径CdnURL          string // cdn地址,用户缓存静态资源QiniuAccessKey  string // 使用七牛云存储图片资源QiniuSecretKey  stringValine          bool // 评论系统用的ValineValineAppid     stringValineAppkey    stringValineServerURL string
}

其余数据基本是从DB获取的,与DB交互的结构体,我们一般会单独建立model文件夹存放。
models/post.go

package modelsimport ("goblog/config""html/template""time"
)// 用于与DB交互,与DB中字段一一对应
type Post struct {Pid        int       `json:"pid"`        // 文章IDTitle      string    `json:"title"`      // 文章标题Slug       string    `json:"slug"`       // 自定义页面 pathContent    string    `json:"content"`    // 文章的htmlMarkdown   string    `json:"markdown"`   // 文章的MarkdownCategoryId int       `json:"categoryId"` //分类idUserId     int       `json:"userId"`     //用户idViewCount  int       `json:"viewCount"`  //查看次数Type       int       `json:"type"`       //文章类型 0 普通,1 自定义文章CreateAt   time.Time `json:"createAt"`   // 创建时间UpdateAt   time.Time `json:"updateAt"`   // 更新时间
}// 用于给前端响应,所以有了分类名称和用户名等信息,而不是分类id或者用户id
type PostMore struct {Pid          int           `json:"pid"`          // 文章IDTitle        string        `json:"title"`        // 文章标题Slug         string        `json:"slug"`         // 自定义页面 pathContent      template.HTML `json:"content"`      // 文章的htmlCategoryId   int           `json:"categoryId"`   // 文章的MarkdownCategoryName string        `json:"categoryName"` // 分类名UserId       int           `json:"userId"`       // 用户idUserName     string        `json:"userName"`     // 用户名ViewCount    int           `json:"viewCount"`    // 查看次数Type         int           `json:"type"`         // 文章类型 0 普通,1 自定义文章CreateAt     string        `json:"createAt"`UpdateAt     string        `json:"updateAt"`
}type PostReq struct {Pid        int    `json:"pid"`Title      string `json:"title"`Slug       string `json:"slug"`Content    string `json:"content"`Markdown   string `json:"markdown"`CategoryId int    `json:"categoryId"`UserId     int    `json:"userId"`Type       int    `json:"type"`
}type SearchResp struct {Pid   int    `orm:"pid" json:"pid"` // 文章IDTitle string `orm:"title" json:"title"`
}type PostRes struct {config.Viewerconfig.SystemConfigArticle PostMore
}

models/home.go

用于封装前端需要的首页数据

package modelsimport "goblog/config"type HomeResponse struct {config.ViewerCategorys []CategoryPosts     []PostMoreTotal     intPage      intPages     []intPageEnd   bool // 当前页是否是最后一页,决定分页那里是否显示左右箭头
}

四、配置文件加载

这里配置文件我们用的toml,实际工作中可能yaml用的更多一点。

config/config.toml

[viewer]Title = "Go语言博客"Description = "Go语言博客"Logo = "/resource/images/logo.png"Navigation = ["首页","/", "GO语言","/golang", "归档","/pigeonhole", "关于","/about"]Bilibili = "https://space.bilibili.com/473844125"Zhihu = "https://www.zhihu.com/people/ma-shen-zhi-lu"Avatar = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13147603927%2F1000.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1647242040&t=c6108010ed46b4acebe18955acdd2d24"UserName = "张三"UserDesc = "长得非常帅的程序员"
[system]CdnURL = "https://static.mszlu.com/goblog/es6/md-assets"QiniuAccessKey = "替换自己的"QiniuSecretKey = "替换自己的"Valine = trueValineAppid = "替换自己的"ValineAppkey = "替换自己的"ValineServerURL = "替换自己的"

toml文件我们可以使用github.com/BurntSushi/toml包,获取

 go get github.com/BurntSushi/toml

配置文件加载,常规套路是定义全局变量,使用init加载

config/config.go

package configimport ("os""github.com/BurntSushi/toml"
)var Cfg *TomlConfigfunc init() {Cfg = new(TomlConfig)var err errorCfg.System.CurrentDir, err = os.Getwd()if err != nil {panic(any(err))}Cfg.System.AppName = "lym-go-blog"Cfg.System.Version = 1.0_, err = toml.DecodeFile("config/config.toml", &Cfg)if err != nil {panic(any(err))}
}type TomlConfig struct {Viewer ViewerSystem SystemConfig
}type Viewer struct {Title       string   // 首页标题Description string   // 首页描述Logo        string   // 博客系统logoNavigation  []string // 导航栏Bilibili    string   // bilibiliAvatar      string   // 头像UserName    string   // 用户名UserDesc    string   // 用户描述
}// 系统相关配置
type SystemConfig struct {AppName         stringVersion         float32CurrentDir      string // 项目路径CdnURL          string // cdn地址,用户缓存静态资源QiniuAccessKey  string // 使用七牛云存储图片资源QiniuSecretKey  stringValine          bool // 评论系统用的ValineValineAppid     stringValineAppkey    stringValineServerURL string
}

五、构造假数据- - -显示首页内容

main.go

注意看代码注释

package mainimport ("goblog/config""goblog/models""html/template""log""net/http""time"
)type IndexData struct {Title string `json:"title"`Desc  string `json:"desc"`
}// 前端html页面中使用了一些函数,所以这里需要定义一下
// 是否偶数
func IsODD(num int) bool {return num%2 == 0
}func GetNextName(strs []string, index int) string {return strs[index+1]
}// 日期按指定格式转换
func Date(layout string) string {return time.Now().Format(layout)
}func index(w http.ResponseWriter, r *http.Request) {t := template.New("index.html")// 拿到当前的路径path := config.Cfg.System.CurrentDir//访问博客首页模板的时候,因为有多个模板的嵌套,解析文件的时候,需要将其涉及到的所有模板都进行解析home := path + "/template/home.html"header := path + "/template/layout/header.html"footer := path + "/template/layout/footer.html"personal := path + "/template/layout/personal.html"post := path + "/template/layout/post-list.html"pagination := path + "/template/layout/pagination.html" // 页码// 定义模板中需要用到的函数t.Funcs(template.FuncMap{"isODD": IsODD, "getNextName": GetNextName, "date": Date})t, err := t.ParseFiles(path+"/template/index.html", home, header, footer, personal, post, pagination)if err != nil {log.Println(err)}//页面上涉及到的所有的数据,必须有定义var categorys = []models.Category{{Cid:  1,Name: "go",},{Cid:  2,Name: "python",},}var posts = []models.PostMore{{Pid:          1,Title:        "go博客",Content:      "这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容",UserName:     "张三",ViewCount:    123,CreateAt:     "2023-12-17",CategoryId:   1,CategoryName: "go",Type:         0,},{Pid:          2,Title:        "这是第二篇博客",Content:      "这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容",UserName:     "李四",ViewCount:    1314,CreateAt:     "2023-12-17",CategoryId:   1,CategoryName: "go",Type:         0,},}var hr = &models.HomeResponse{Viewer:    config.Cfg.Viewer,Categorys: categorys,Posts:     posts,Total:     2,Page:      1,Pages:     []int{1},PageEnd:   true,}t.Execute(w, hr)
}func main() {//程序入口,一个项目 只能有一个入口//web程序,http协议 ip portserver := http.Server{Addr: "127.0.0.1:8080",}http.HandleFunc("/", index)// 因为静态文件放到了public/resource目录下,但是页面中写路径的时候都写的resource,所以这里转一下http.Handle("/resource/", http.StripPrefix("/resource/", http.FileServer(http.Dir("public/resource/"))))if err := server.ListenAndServe(); err != nil {log.Println(err)}
}

此时通过流量器访问8080端口,便可看到如下界面了

在这里插入图片描述

相关文章:

go原生http开发简易blog(一)项目简介与搭建

文章目录 一、项目简介二、项目搭建前置知识三、首页- - -前端文件与后端结构体定义四、配置文件加载五、构造假数据- - -显示首页内容 代码地址&#xff1a;https://gitee.com/lymgoforIT/goblog 一、项目简介 使用Go原生http开发一个简易的博客系统&#xff0c;包含一下功能…...

[足式机器人]Part4 南科大高等机器人控制课 Ch09 Dynamics of Open Chains

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;CLEAR_LAB 笔者带更新-运动学 课程主讲教师&#xff1a; Prof. Wei Zhang 南科大高等机器人控制课 Ch09 Dynamics of Open Chains 1. Introduction1.1 From Single Rigid Body to Open Chains1.2 Preview of Open-Chain …...

概率论复习

第一章&#xff1a;随机概率及其概率 A和B相容就是 AB 空集 全概率公式与贝叶斯公式&#xff1a; 伯努利求概率&#xff1a; 第二章&#xff1a;一维随机变量及其分布&#xff1a; 离散型随机变量求分布律&#xff1a; 利用常规离散性分布求概率&#xff1a; 连续性随机变量…...

ES客户端RestHighLevelClient的使用

1 RestHighLevelClient介绍 默认情况下&#xff0c;ElasticSearch使用两个端口来监听外部TCP流量。 9200端口&#xff1a;用于所有通过HTTP协议进行的API调用。包括搜索、聚合、监控、以及其他任何使用HTTP协议的请求。所有的客户端库都会使用该端口与ElasticSearch进行交互。…...

GitHub入门命令介绍

GitHub是当今最受欢迎的代码托管平台之一&#xff0c;它提供了强大的版本控制和协作功能。 对于初学者来说&#xff0c;熟悉GitHub的基本命令非常重要。下面介绍一些常用的GitHub命令。 一、安装Git 1. Windows系统&#xff1a;在Windows上使用GitHub之前&#xff0c;您需要先…...

EasyExcel 简单导入

前边写过使用easyexcel进行简单、多sheet页的导出。今天周日利用空闲写一下对应简单的导入。 重点&#xff1a;springboot、easyExcel、桥接模式&#xff1b; 说明&#xff1a;本次使用实体类student&#xff1a;属性看前边章节内容&#xff1b; 1、公共导入service public …...

Termux搭建nodejs环境

安装nodejs ~ $ pkg install nodejs使用http-server搭建文件下载服务 先安 http-server 并启动 # 安装 http-server 包 ~ $ npm install -g http-server# 启动 http-server 服务 ~ $ http-server Starting up http-server, serving ./http-server version: 14.1.1http-serve…...

喜报丨迪捷软件入选2023年浙江省信息技术应用创新典型案例

12月6日&#xff0c;浙江省经信厅公示了2023年浙江省信息技术应用创新典型案例入围名单。本次案例征集活动&#xff0c;由浙江省经信厅、省密码管理局、工业和信息化部网络安全产业发展中心联合组织开展&#xff0c;共遴选出24个优秀典型解决方案&#xff0c;迪捷软件“基于全数…...

C语言连接zookeeper客户端(不能完全参考官网教程)

准备过程 1.通过VStudio 远程连接linux的开发环境&#xff1b; 2.g环境&#xff0c;通过MingW安装&#xff1b; 3.必须要安装好pthread.h的环境&#xff0c;不管是windows端&#xff08;linux 可视化端开发就不管这个&#xff09;还是linux端&#xff1b; 4.需要准备zookeeper…...

python排序

0. 背景 Python排序功能十分强大&#xff0c;可以进行基本排序或自定义排序。Python中提供两种不同的排序方法对各种各样的数据类型进行排序。 1. 使用sorted()函数排序 排序主要是对相同数据类型的元素进行的&#xff0c;包括数值和字符串两种数据类型。 1.1 对数值进行排…...

【Spark精讲】Spark Shuffle详解

目录 Shuffle概述 Shuffle执行流程 总体流程 中间文件 ShuffledRDD生成 Stage划分 Task划分 Map端写入(Shuffle Write) Reduce端读取(Shuffle Read) Spark Shuffle演变 SortShuffleManager运行机制 普通运行机制 bypass 运行机制 Tungsten Sort Shuffle 运行机制…...

【C++初阶】八、初识模板(泛型编程、函数模板、类模板)

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 【C初阶】七、内存管理 &#xff08;C/C内存分布、C内存管理方式、operator new / delete 函数、定位new表达式&#xff09; -CSDN博客 目录 一 . 泛型编程 二 . 函数模板 函数模板…...

珠海数字孪生赋能工业智能制造,助力制造业企业数字化转型

珠海数字孪生赋能工业智能制造&#xff0c;助力制造业企业数字化转型。数字孪生是利用物理模型、传感器更新及运行历史数据&#xff0c;集成多物理量、多尺度的仿真过程。巨蟹数科数字孪生通过构建物理车间与虚拟车间之间的有效映射并实时反馈机制&#xff0c;实现物理车间与虚…...

HarmonyOS开发实战:如何实现一个运动排名榜页面

HarmonyOS开发实战&#xff1a;如何实现一个运动排名榜页面 代码仓库&#xff1a; 运动排名榜页面 项目介绍 本项目使用声明式语法和组件化基础知识&#xff0c;搭建一个可刷新的排行榜页面。在排行榜页面中&#xff0c;使用循环渲染控制语法来实现列表数据渲染&#xff0c;…...

2019年第八届数学建模国际赛小美赛D题安全选举的答案是什么解题全过程文档及程序

2019年第八届数学建模国际赛小美赛 D题 安全选举的答案是什么 原题再现&#xff1a; 随着美国进入一场关键性的选举&#xff0c;在确保投票系统的完整性方面进展甚微。2016年总统大选期间&#xff0c;唐纳德特朗普因被指控受到外国干涉而入主白宫&#xff0c;这一问题再次成为…...

vivado 创建实施约束

创建实施约束 在您有了一个合成的网表之后&#xff0c;您可以将它与XDC文件一起加载到内存中&#xff0c;或者Tcl脚本已启用以进行实现。当加载XDC以便验证和更正任何不能应用的约束。在某些情况下&#xff0c;合成网表中的对象名称与精心设计。如果是这种情况&#xff0c;则必…...

【代码分析】MPI

代码解读 问题 model/AdaMPI.py:21 为什么下降分辨率model.CPN.unet.FeatMaskNetwork 为什么用的是mask&#xff0c;unet&#xff1f; MPI class MPIPredictor(nn.Module):def __init__(self,width384,height256,num_planes64,):super(MPIPredictor, self).__init__()self.…...

数字孪生Web3D智慧机房可视化运维云平台建设方案

前言 进入信息化时代&#xff0c;数字经济发展如火如荼&#xff0c;数据中心作为全行业数智化转型的智慧基座&#xff0c;重要性日益凸显。与此同时&#xff0c;随着东数西算工程落地和新型算力网络体系构建&#xff0c;数据中心建设规模和业务总量不断增长&#xff0c;机房管理…...

飞天使-docker知识点12-docker-compose

文章目录 docker-compose命令启动单个容器重启容器停止和启动容器停止和启动所有容器演示一个简单示范 docker-compose 部署有依赖问题 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它允许您使用简单的 YAML 文件来配置应用程序的服务、网络和存储等方…...

快速排序(一)

目录 快速排序&#xff08;hoare版本&#xff09; 初级实现 问题改进 中级实现 时空复杂度 高级实现 三数取中 快速排序&#xff08;hoare版本&#xff09; 历史背景&#xff1a;快速排序是Hoare于1962年提出的一种基于二叉树思想的交换排序方法 基本思想&#xff1a…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...