提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
热加载
热加载和热部署是软件开发中经常使用的概念,它们可以使得应用程序在不停止服务的情况下进行代码更新和实现,进而提高代码修改的效率。具体来说:
热加载:Java中热加载是指在应用程序运行期间,动态地将新的类加载到 Java 虚拟机(JVM)中。相比于重启服务器的方式,热加载可以更方便地进行代码修改和测试。Tomcat 使用后台线程进行周期性检查,并通过反射机制动态加载新的类,从而实现了热加载机制。
热部署:Java中热部署是指在应用程序运行期间,重新部署Web应用程序,以达到更新应用程序的目的。与热加载不同的是,原 Context 对象会被整个销毁,因此该 Context 所关联的一切资源都会被销毁,包括 Session。在 Tomcat 中,热部署由 Host 容器实现,因为热部署过程中 Context 容器会被销毁。
在写程序时,我们要引入很多配置信息,如数据库的配置信息等,一旦这些信息发生改变,我们就要重启程序,来使配置生效。在go中,基于viper的动态配置可以解决这个问题。下面就是一个简单的viper热加载示例
项目结构
base.yaml
service:
mysql:
host: 127.0.0.2
port: 3000
config.go
热加载的关键是dynamicConfig()这个函数
package util
import (
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
var GlobalConfig *viper.Viper
func init() {
initConfig()
go dynamicConfig()
}
func initConfig() {
GlobalConfig = viper.New()
GlobalConfig.SetConfigName("base") // 配置文件名称
GlobalConfig.AddConfigPath("config") // 从当前目录的哪个文件开始查找
GlobalConfig.SetConfigType("yaml") // 配置文件的类型
err := GlobalConfig.ReadInConfig() // 读取配置文件
if err != nil { // 可以按照这种写法,处理特定的找不到配置文件的情况
if v, ok := err.(viper.ConfigFileNotFoundError); ok {
fmt.Println(v)
} else {
panic(fmt.Errorf("read config err:%s\n", err))
}
}
}
// viper支持应用程序在运行中实时读取配置文件的能力。确保在调用 WatchConfig()之前添加所有的configPaths。
func dynamicConfig() {
GlobalConfig.WatchConfig()
GlobalConfig.OnConfigChange(func(event fsnotify.Event) {
fmt.Printf("发现配置信息发生变化: %s\n", event.String())
})
}
main.go
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"test/util"
)
func main() {
gin.SetMode(gin.ReleaseMode)
r := gin.Default()
r.GET("/ping", func(context *gin.Context) {
fmt.Println("当前host是: ", util.GlobalConfig.GetString("service.mysql.host"))
fmt.Println("当前port是: ", util.GlobalConfig.GetString("service.mysql.port"))
context.JSON(
200, gin.H{
"host": util.GlobalConfig.GetString("service.mysql.host"),
"port": util.GlobalConfig.GetString("service.mysql.port"),
})
})
port := util.GlobalConfig.GetString("service.mysql.port")
port = ":" + port
r.Run(port)
}
演示
访问http://localhost:3000/ping,如下
然后现在修改base.yaml里面的host和port值,但不要重启服务,只用刷新网页,如下