在 Go 语言中使用 `go-sql-driver/mysql`(即 `github.com/go-sql-driver/mysql`)作为 MySQL 驱动时,连接字符串中的 `loc` 参数用于指定驱动在处理 `DATETIME` 和 `TIMESTAMP` 类型时所使用的 **本地时区(Local Time Zone)**。 --- ## 一、`loc` 参数的作用 - `loc` 指定的是 **Go 程序解析和格式化时间时使用的时区**。 - 它 **不会改变 MySQL 服务器本身的时区设置**,而是影响 Go 驱动如何将数据库中的时间值转换为 Go 的 `time.Time` 类型,以及如何将 `time.Time` 写入数据库。 语法示例: ```go db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/dbname?loc=Asia%2FShanghai") ``` 其中 `Asia/Shanghai` 是 IANA 时区名称,URL 编码后为 `Asi...
 发布日期: 2025-11-20    分类: Go    浏览量: 68  
# Go Web 应用性能pprof分析完整指南 在构建高性能的 Go Web 应用时,性能分析(Profiling)是不可或缺的一环。Go 语言原生提供了强大且易用的性能分析工具,本文将系统性地介绍如何对 Go Web 应用进行 CPU、内存、阻塞、协程等维度的性能分析,并提供可直接复用的代码模板和操作步骤。 ## 一、准备工作:启用 pprof Go 的标准库 `net/http/pprof` 提供了 HTTP 接口访问性能分析数据的能力。只需在你的 Web 应用中导入该包即可自动注册相关路由: ```go import _ "net/http/pprof" ``` > 注意:仅在开发或测试环境中暴露 pprof 端点。生产环境应通过权限控制或独立管理端口暴露,避免安全风险。 ### 示例:最小可运行 Web 应用 + pprof ```go package main import ( "net/http" _ "net/http/pprof" // 自动注册 /debug/pprof 路由 ) fu...
 发布日期: 2025-11-20    分类: Go    浏览量: 55  
GORM模型查询生成器生成的模型代码,创建数据的时候如果time.Time类型的属性未赋值,`create`将会报错: `incorrect datetime value '0000-0-0 00:00:00' for column` 有几种方法能让GORM忽略未赋值的time字段,使用数据库默认的NULL: - 使用`Omit`忽略指定的未赋值字段 - 模型数据类型`time.Time`改成`*time.Time` - 把模型gorm的tag改成`gorm:"default:null"` - 把模型数量类型改成`sql.NullTime`,新加模型赋值时需要赋值`sql.NullTime{}`...
 发布日期: 2025-02-24    分类: Go    浏览量: 6183  
**知识点:** - udp 协议是无连接的协议,发送数据前不需要先和数据接收方建立连接。 - 每个 UDP socket 都有一个接收缓冲区,没有发送缓冲区,从概念上来说就是只要有数据就发,不管对方是否可以正确接收,所以不缓冲,不需要发送缓冲区。 - 当socket 接收缓冲区满时,新来的数据报无法进入接收缓冲区,此数据报就被丢弃。UDP是没有流量控制的;快的发送者可以很容易地就淹没慢的接收者,导致接收方的 UDP 丢弃数据报。 - UDP每个数据包之间有界限,每次接收都是一个完整的数据包,即使被下层的ip协议分片传输(udp包大于ip包的最大传输单元)。 - ip分片传输,某个片丢失,那么整个udp包都会被丢弃,上层应用不知道udp包被丢弃。 ## 单播 单播就是点对点通信,用于两个主机之间端对端的通信。 **服务端主要函数:** - `net.ListenUDP`: 监听`udp`端口 - `ReadFromUDP`: 读取连接数据 - `WriteToUDP`: 写入数据 由于udp是无连接的协议,所以服务端读和写都要...
 发布日期: 2024-07-31    分类: Go    浏览量: 5455  
可观测性主要包括三个方面:追踪(traces)、指标(metrics)和日志(logs)。 OpenTelemetry 的指标功能还是测试状态,没有实现日志的功能,日志可以用其他流行的日志库记录,然后收集到类似ELK的日志系统里面。 追踪数据存储后端是用`jaeger`,指标数据存储后端是用`prometheus`。 前面几个文章实现的是追踪,本文主要讲一下指标。 指标数据直接用`prometheus`的go客户端生成也是一样的,不一定需要用`OpenTelemetry`提供的库。 `OpenTelemetry`的方式是先创建`exporter`和`provider`,之后就可以生成指标了,`main.go`: ```go import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "go.opentelemetry.io/otel/attribute" p...
 发布日期: 2023-05-17    分类: Go    浏览量: 2349  
[上一篇文章](https://360us.net/article/87.html)用的是http协议做服务间的调用协议,这篇改成gRPC。 首先安装包`otelgrpc`: ```shell go get go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc ``` 创建一个`api`目录,创建`rpc.proto`文件: ```protobuf syntax = "proto3"; package api; // advanced目录执行编译: protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative api/rpc.proto option go_package ="github.com/ilaziness/gopkg/opentelemetry/as/api"; service AsRp...
 发布日期: 2023-05-14    分类: Go    浏览量: 1865  
从上一篇入门:[https://www.360us.net/article/86.html](https://www.360us.net/article/86.html)我们知道用OpenTelemetry实现应用的可观测性需要三个部分: - `exporter`:负责遥测数据输出,可以输出到控制台,文件,后端存储或者中间的收集节点服务器。 - `instrumentation `:这个部分就是产生追踪数据,也就是创建`span`。 - `TracerProvider`:扮演了中间角色,把生成的遥测数据输出到`exporter`。 目前Go是不支持自动追踪的,一些公共库可以在这里https://opentelemetry.io/ecosystem/registry/?language=go 找到封装好的追踪代码。 比如`otelhttp`是对`net/http`的包装,还有`gin`,`gRPC`的等等,自己的私有库、包、或者函数就需要自己手动添加代码了。 本文的内容是实现在多个服务之间的追踪。 创建三个服务,分别是`main`、`as sevice`...
 发布日期: 2023-05-11    分类: Go    浏览量: 1793  
> 本文定位是快速入门,理解OpenTelemetry在go里面的基本使用 > > 参考文档:https://opentelemetry.io/docs/instrumentation/go/getting-started Go 版本需要是1.16以上。 创建一个名字是`fib`的go项目,就一个功能计算斐波那契数列。 创建三个文件: `fib.go`测试项目的核心,功能是计算斐波那契数列。 ```go package main import "fmt" // Fibonacci 计算斐波那契数 func Fibonacci(n uint) (uint64, error) { if n ...
 发布日期: 2023-05-09    分类: Go    浏览量: 1807  
## 语言变化 ### slice转数组 Go1.17在语言层面开始支持将slice转为指向数组的指针。 示例如下: ```go s := make([]byte, 2, 4) // 将s这个slice转为指向byte数组的指针s0 // 其中[0]byte里的0表示数组的长度,虽然长度为0,但值不等于nil s0 := (*[0]byte)(s) // s0 != nil fmt.Printf("%T") // 将s[1:]这个slice转为指向byte数组的指针s1 // s1指向的数组的长度为1 s1 := (*[1]byte)(s[1:]) // &s1[0] == &s[1] // 将s这个slice转为指向byte数组的指针s2 // s2指向的数组的长度为2 s2 := (*[2]byte)(s) // &s2[0] == &s[0] // 将s这个slice转为指向byte数组的指针s4 // s4指向的数组的长度为4 s4 := (*[4]byte)(s) // panics: len...
 发布日期: 2023-03-04    分类: Go    浏览量: 1467  
基于ZooKeeper和etcd实现服务的注册和发现功能的原理。 ## ZooKeeper ### 服务注册 利用临时节点的特性,创建一个服务的临时节点,写入服务信息数据,不断监视节点续期,当服务不可用时会话超时,临时节点会被删除。 ### 服务发现 服务发现是利用`watch`的特性,首先获取一遍需要的服务信息,保存在本地,然后给这个服务节点添加`watch`,监视变化和更新。 ## etcd ### 服务注册 服务注册是利用了etcd租约的特性。 首先创建一个定时的租约,比如10秒,20秒等。 然后带租约存储服务信息,不断的续期租约,当服务不可用时,租约过期,服务数据就会被删除,就相当于心跳保活了。 ### 服务发现 服务发现和zookepper类似,是利用了etcd的`watch`的特性,首先获取一遍需要的服务的信息,再监视变化和更新。 下面是实现代码供参考: https://github.com/ilaziness/gopkg/tree/main/serviceregdisc...
 发布日期: 2023-01-17    分类: Go    浏览量: 1311