主要包括
http服务,tcp服务,Grpc服务,多租户功能,后台管理系统(前端vue-element-admin,后端Gin-scafolld)。
实现细节
http服务主要包含
1:服务启动时从DB加载配置信息到内存中。
2:反向代理以中间件,组册到中间件最后一级。
3:websocket,请求超时控制,限流白名单,组间到中间件。
tcp服务主要包含
1:服务启动时从DB加载配置信息到内存中。
2:反向代理以中间件,组册到中间件最后一级。
3:限流,白名单,均以中间件形式组册到服务器上。
Grpc服务主要包括
1:服务启动时从DB加载配置信息到内存中。
2:反向代理以中间件,组册到中间件最后一级。
3:head头转换,限流,白名单转换。
前端:
1:框架选用vue-element-admin。
2:图标选型使用echarts。
后端:
1:SQL数据表。
2:框架选用gin-scafolld。
3:登陆,退出,修改密码。
多租户功能
1:独立URL获取JWT的token。
2:JWT验证token信息。
3:租户列表。
4:租户信息CRUD。
5:流量统计。
实现原理

TCP连接代码:
package tcp_server
import (
"context"
"fmt"
"net"
"runtime"
)
type tcpKeepAliveListener struct {
*net.TCPListener
}//设定监听者
func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
tc, err := ln.AcceptTCP()
if err != nil {
return nil, err
}
return tc, nil
}
type contextKey struct {
name string
}
func (k *contextKey) String() string {
return "tcp_proxy context value " + k.name//代理机器的编号
}
type conn struct {
server *TcpServer
cancelCtx context.CancelFunc
rwc net.Conn
remoteAddr string
}
func (c *conn) close() {
c.rwc.Close()
}
func (c *conn) serve(ctx context.Context) {
defer func() {
if err := recover(); err != nil && err != ErrAbortHandler {
const size = 64 << 10
buf := make([]byte, size)
buf = buf[:runtime.Stack(buf, false)]
fmt.Printf("tcp: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
}
c.close()
}()
c.remoteAddr = c.rwc.RemoteAddr().String()
ctx = context.WithValue(ctx, LocalAddrContextKey, c.rwc.LocalAddr())
if c.server.Handler == nil {
panic("handler empty")
}
c.server.Handler.ServeTCP(ctx, c.rwc)
}
TCP的server代码:
package tcp_server
import (
"context"
"fmt"
"errors"
"net"
"sync"
"sync/atomic"
"time"
)
var (
ErrServerClosed = errors.New("tcp: Server closed")
ErrAbortHandler = errors.New("tcp: abort TCPHandler")
ServerContextKey = &contextKey{"tcp-server"}
LocalAddrContextKey = &contextKey{"local-addr"}
)
type onceCloseListener struct {
net.Listener
once sync.Once
closeErr error
}
func (oc *onceCloseListener) Close() error {
oc.once.Do(oc.close)
return oc.closeErr
}
func (oc *onceCloseListener) close() {
oc.closeErr = oc.Listener.Close()
}
type TCPHandler interface {
ServeTCP(ctx context.Context, conn net.Conn)
}
type TcpServer struct {
Addr string
Handler TCPHandler
err error
BaseCtx context.Context
WriteTimeout time.Duration
ReadTimeout time.Duration
KeepAliveTimeout time.Duration
mu sync.Mutex
inShutdown int32
doneChan chan struct{}
l *onceCloseListener
}
func (s *TcpServer) shuttingDown() bool {
return atomic.LoadInt32(&s.inShutdown) != 0
}
func (srv *TcpServer) ListenAndServe() error {
if srv.shuttingDown() {
return ErrServerClosed
}
if srv.doneChan == nil {
srv.doneChan = make(chan struct{})
}
addr := srv.Addr
if addr == "" {
return errors.New("need addr")
}
ln, err := net.Listen("tcp", addr)
if err != nil {
return err
}
return srv.Serve(tcpKeepAliveListener{
ln.(*net.TCPListener)})
}
func (srv *TcpServer) Close() error {
atomic.StoreInt32(&srv.inShutdown, 1)
close(srv.doneChan) //关闭channel
srv.l.Close() //执行listener关闭
return nil
}
func (srv *TcpServer) Serve(l net.Listener) error {
srv.l = &onceCloseListener{Listener: l}
defer srv.l.Close() //执行listener关闭
if srv.BaseCtx == nil {
srv.BaseCtx = context.Background()
}
baseCtx := srv.BaseCtx
ctx := context.WithValue(baseCtx, ServerContextKey, srv)
for {
rw, e := l.Accept()
if e != nil {
select {
case <-srv.getDoneChan():
return ErrServerClosed
default:
}
fmt.Printf("accept fail, err: %v\n", e)
continue
}
c := srv.newConn(rw)
go c.serve(ctx)
}
return nil
}
func (srv *TcpServer) newConn(rwc net.Conn) *conn {
c := &conn{
server: srv,
rwc: rwc,
}
// 设置参数
if d := c.server.ReadTimeout; d != 0 {
c.rwc.SetReadDeadline(time.Now().Add(d))
}
if d := c.server.WriteTimeout; d != 0 {
c.rwc.SetWriteDeadline(time.Now().Add(d))
}
if d := c.server.KeepAliveTimeout; d != 0 {
if tcpConn, ok := c.rwc.(*net.TCPConn); ok {
tcpConn.SetKeepAlive(true)
tcpConn.SetKeepAlivePeriod(d)
}
}
return c
}
func (s *TcpServer) getDoneChan() <-chan struct{} {
s.mu.Lock()
defer s.mu.Unlock()
if s.doneChan == nil {
s.doneChan = make(chan struct{})
}
return s.doneChan
}
func ListenAndServe(addr string, handler TCPHandler) error {
server := &TcpServer{Addr: addr, Handler: handler, doneChan: make(chan struct{}),}
return server.ListenAndServe()
}
版权声明:本文为weixin_52033496原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。