有:您可以使用
tls.Config的
GetCertificate成员而不是填充
Certificates。首先,定义一个封装证书和重载功能的数据结构(
SIGHUP在此示例中,在接收到信号时):
type keypairReloader struct { certMu sync.RWMutex cert *tls.Certificate certPath string keyPath string}func NewKeypairReloader(certPath, keyPath string) (*keypairReloader, error) { result := &keypairReloader{ certPath: certPath, keyPath: keyPath, } cert, err := tls.LoadX509KeyPair(certPath, keyPath) if err != nil { return nil, err } result.cert = &cert go func() { c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGHUP) for range c { log.Printf("Received SIGHUP, reloading TLS certificate and key from %q and %q", *tlsCertPath, *tlsKeyPath) if err := result.maybeReload(); err != nil { log.Printf("Keeping old TLS certificate because the new one could not be loaded: %v", err) } } }() return result, nil}func (kpr *keypairReloader) maybeReload() error { newCert, err := tls.LoadX509KeyPair(kpr.certPath, kpr.keyPath) if err != nil { return err } kpr.certMu.Lock() defer kpr.certMu.Unlock() kpr.cert = &newCert return nil}func (kpr *keypairReloader) GetCertificateFunc() func(*tls.ClientHelloInfo) (*tls.Certificate, error) { return func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) { kpr.certMu.RLock() defer kpr.certMu.RUnlock() return kpr.cert, nil }}然后,在您的服务器代码中,使用:
kpr, err := NewKeypairReloader(*tlsCertPath, *tlsKeyPath)if err != nil { log.Fatal(err)}srv.TLSConfig.GetCertificate = kpr.GetCertificateFunc()我最近在RobustIRC中实现了这种模式。



