> # OSS 和 CDN
- OSS 作為源站,CDN 提供加速
* **OSS**:核心是“存儲”,解決數據可靠保存問題。
* **CDN**:核心是“加速”,解決訪問速度和高并發問題。
* **搭配使用**:用 OSS 存儲資源,通過 CDN 提供快速分發和訪問,是現代應用常見的最佳實踐。
> # mysqldump 導出數據
- 用 Navicat 導出表結構和數據(每一行數據是一條insert語句)

- 使用 mysqldump 導出數據 (一次性insert多條數據的value)
- mysqldump -u root -p mydatabase mytable > mytable_dump.sql

- 用命令行導入數據(Navicat 導入可能會報錯):
mysql -u root -p mydatabase < mytable_dump.sql
> # mysql報錯
- Too many connections: 數據庫的同時連接數超出了服務器允許的最大值
- show variables like 'max_connections';
- Invalid connection:連接可能因為空閑超時或網絡問題失效。
- show variables like '%wait_timeout%';
- **Lost connection to MySQL server during query**
- Lost connection to MySQL server during query: 查詢時間過長,或服務器的 `wait_timeout` 或 `interactive_timeout` 太短
- Lock wait timeout exceeded; try restarting transaction
- Deadlock found when trying to get lock; try restarting transaction
> # 正無窮大,負無窮大,無效數字
~~~
package main
import (
"fmt"
"math"
)
func main() {
num1 := math.Inf(1) //正無窮大
num2 := math.Inf(-1) //負無窮大
num3 := math.NaN() //無效數字
fmt.Println(num1, num2, num3)
fmt.Println(math.Inf(1) == math.Inf(1)) //true
fmt.Println(math.Inf(-1) == math.Inf(-1)) //true
fmt.Println(math.NaN() == math.NaN()) //false
}
~~~
> # gzip
- 服務端代碼
- 二進制的壓縮率比較低
- 對重復數據,壓縮率極高 (日常接口返回的json數據可以壓縮5倍,8倍)
~~~
package main
import (
"bytes"
"compress/gzip"
"encoding/json"
"fmt"
"math/rand"
"net/http"
"strings"
"time"
)
// 模擬大數據結構
type LargeData struct {
ID int `json:"id"`
Name string `json:"name"`
Content string `json:"content"`
}
// 生成大數據
func generateRandomString(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
seededRand := rand.New(rand.NewSource(time.Now().UnixNano()))
builder := strings.Builder{}
builder.Grow(length)
for i := 0; i < length; i++ {
builder.WriteByte(charset[seededRand.Intn(len(charset))])
}
return builder.String()
}
// generateLargeData generates a slice of LargeData with unique and random content
func generateLargeData() []LargeData {
var data []LargeData
uniqueNames := make(map[string]bool)
for i := 0; i < 1000; i++ {
// Generate a unique name
var name string
for {
name = fmt.Sprintf("Item-%s", generateRandomString(10))
if !uniqueNames[name] {
uniqueNames[name] = true
break
}
}
data = append(data, LargeData{
ID: i,
Name: name,
Content: generateRandomString(250), // Random content of 250 characters
})
}
return data
}
// 壓縮數據為 Gzip 格式
func compressGzip(data []byte) ([]byte, error) {
var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
_, err := gz.Write(data)
if err != nil {
return nil, err
}
gz.Close()
return buf.Bytes(), nil
}
// HTTP 處理函數
func handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*") // 允許所有來源
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS") // 允許的 HTTP 方法
w.Header().Set("Access-Control-Allow-Headers", "Content-Encoding") // 允許的自定義頭
// 生成大數據
data := generateLargeData()
// 序列化為 JSON
jsonData, err := json.Marshal(data)
if err != nil {
http.Error(w, "Error generating data", http.StatusInternalServerError)
return
}
// 檢查客戶端是否支持 Gzip
acceptEncoding := r.Header.Get("Accept-Encoding")
if strings.Contains(acceptEncoding, "gzip") {
// 壓縮數據
compressedData, err := compressGzip(jsonData)
if err != nil {
http.Error(w, "Error compressing data", http.StatusInternalServerError)
return
}
// 設置響應頭
w.Header().Set("Content-Encoding", "gzip")
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(compressedData)))
fmt.Println(len(jsonData))
fmt.Println(len(compressedData))
// 寫入壓縮數據
w.Write(compressedData)
} else {
// 客戶端不支持 Gzip,直接返回未壓縮數據
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(jsonData)))
// 寫入未壓縮數據
w.Write(jsonData)
}
}
func main() {
// 注冊路由
http.HandleFunc("/data", handler)
// 啟動 HTTP 服務器
fmt.Println("Starting server on :8080")
http.ListenAndServe(":8080", nil)
}
~~~
- 客戶端代碼
~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fetch Gzip Data</title>
</head>
<body>
<h1>Fetch Gzip-compressed Data</h1>
<button id="fetchDataButton">Fetch Data</button>
<pre id="result"></pre>
<script>
document.getElementById('fetchDataButton').addEventListener('click', async () => {
try {
// 發起 GET 請求
const response = await fetch('http://localhost:8080/data', {
method: 'GET',
headers: {
'Accept-Encoding': 'gzip', // 告訴服務端客戶端支持 Gzip
}
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
// 解析 JSON 數據
const data = await response.json();
// 顯示返回的數據
document.getElementById('result').textContent = JSON.stringify(data, null, 2);
} catch (error) {
console.error('Error fetching data:', error);
document.getElementById('result').textContent = `Error: ${error.message}`;
}
});
</script>
</body>
</html>
~~~
榮幸能夠成為公司的一員,以后請大家多多
- 目錄
- 第一例 gRPC使用例子
- 第二例 基于go-micro做服務注冊和服務發現
- 第三例 留言板項目源碼
- 第四例 聊天室
- 第五例 工具庫
- dao
- common
- common.go
- config
- config.go
- gorm
- grom.go
- sqlx
- sqlx.go
- kafka
- kafka.go
- log
- log.go
- log2.go
- redis
- redis.go
- zookeeper
- zookeeper.go
- init
- main.go
- 工具庫
- cache
- cfg.go
- redis
- 示例
- database
- cfg.go
- gorm.go
- sql.go
- 示例
- mq
- cfg.go
- kafka_consumer.go
- kafka_producter.go
- 示例
- time
- time.go
- 第六例 原生sql操作
- 第七例 sqlx操作
- 第八例 Redis數據庫(gomodule/redigo)
- 第九例 Redis消息隊列
- 第十例 Redis集群連接
- 十一例 Zookeeper操作
- 十二例 Kafka操作
- 十三例 NSQ操作
- 十四例 二分查找
- 十五例 交換排序 - 冒泡排序
- 十六例 插入排序 - 直接插入排序
- 十七例 插入排序 - 希爾排序
- 十八例 交換排序 - 快速排序
- 十九例 算法求解應用
- 二十例 pprof性能分析
- 二一例 CPU信息采集
- 二二例 Heap信息采集
- 二三例 Http信息采集
- 二四例 單元測試(功能測試)
- 二五例 基準測試(壓力測試/性能測試)
- 二六例 gdb調試
- 二七例 json序列化和反序列化
- 二八例 protobuf序列化和反序列化
- 二九例 包管理工具 go vendor
- 三十例 包管理工具 go mod
- 三一例 zip壓縮
- 三二例 交叉編譯
- 三三例 線上環境部署
- 三四例 業務:實現固定周期維護
- 三五例 聊天室(精簡版)
- 三六例 并發安全字典
- 三七例 導出Excel表格
- 三八例 導出CSV表格
- 三九例 聊天室(高并發)
- 四十例 JWT (Json Web Token)
- 四一例 雪花算法生成 Id
- 四二例 對稱加密 AES
- 四三例 非對稱加密 RSA
- 四四例 簽名算法 SHA1
- 四五例 數據庫操作 gorm
- gorm V2
- 四六例 數據庫操作 gorm 集合
- 數據庫連接和創建表
- 查詢 - 分頁
- 查詢所有數據
- 查詢單條數據
- 插入一條或多條數據
- 更新一條或多條數據
- 更新一條或多條數據(有零值)
- 四七例 RSA(MD5WithRSA 算法)簽名和驗簽方式
- 四八例 線上部署腳本
- 四九例 Elasticsearch
- 五十例 對象池
- 五一例 中間庫(github.com/wong-winnie/library)
- 五二例 二維碼(生成和解析)
- 五三例 回調用例
- 五四例 文件服務器(MINIO)
- 五五例 chm文檔轉json
- 提取內容頁Json
- 將目錄索引和內容頁混合生成Json
- 目錄層級小案例
- 五六例 部署 gogs 代碼管理工具
- 五七例 通過命令行操作SVN
- 五八例 根據數據庫表生產模型
- 五九例 Trie樹
- 六十例 二進制排序
- 六一例 遞歸+迭代實現無限級分類
- 六二例 Arrow 數據結構
- 簡單介紹
- Go 用Arrow數據格式與其它語言交互
- 六三例 LMDB 內存映射型數據庫
- 獲取指定Key位置
- 六四例 切片數據按字段分類
- 六五例 Xorm 批量插入數據
- 六六例 FlatBuffers 序列化和反序列化
- FlatBuffers 步驟1
- FlatBuffers 步驟2
- 六七例 數據同步
- 增量同步v1
- 全量同步v1
- 定時器
- 六八例 Http請求
- 六九例 Gin + 數據庫操作
- 七十例 ClickHouse 列式數據庫
- 七一例 用圖表展示數據庫數據
- 七二例 go:linkname
- 七三例 四舍五入、保留3小數位
- 七四例 判斷兩個時間戳是否同一天
- 七五例 Gin Http請求
- 七六例 過濾器
- 七七例 Excel 導入導出
- 七八例 小程序向公眾號推消息
- 七九列 解析二進制數據
- 例子一
- 例子二
- 八十例 路由轉發
- 八一例 協程池(安全執行任務,捕獲異常)
- 八二例 切片 slice
- 八三例 集合 map
- 八四例 Redis 六種數據類型
- 八五例 Zstd壓縮
- 八六例 提高接口并發量
- 八七例 協程 goroutine 和 通道 channel
- 八七例 Mysql 事務和索引等
- 編寫中
- 數據交互
- mysql 索引和事務
- 發請求
- defer
- 其它
- linux
- OAuth2.0 和 JWT
- 其它2
- 其他
- Web3.0 智能合約
- 多人貪吃蛇
- V1
- 客戶端
- 服務端
- V2
- 同步方式
- 游戲框架
- deepseek
- k8s
- TRPC
- Kafka
- 加密
- mm
- 技術擴展閱讀