add: anowflake email kafka, refa: redis connectg

This commit is contained in:
wwweww
2026-02-25 01:16:13 +08:00
parent fdbcde13b2
commit 300058ad01
67 changed files with 3596 additions and 139 deletions
@@ -0,0 +1,11 @@
package config
import "github.com/zeromicro/go-zero/zrpc"
type Config struct {
zrpc.RpcServerConf
Snowflake struct {
DatacenterId int64
WorkerId int64
}
}
@@ -0,0 +1,33 @@
package logic
import (
"context"
"juwan-backend/app/snowflake/rpc/internal/svc"
"juwan-backend/app/snowflake/rpc/snowflake"
"github.com/zeromicro/go-zero/core/logx"
)
type NextIdLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewNextIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NextIdLogic {
return &NextIdLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *NextIdLogic) NextId(_ *snowflake.NextIdReq) (*snowflake.NextIdResp, error) {
id, err := l.svcCtx.Generator.NextID()
if err != nil {
l.Error("generator.NextID", "err", err)
return nil, err
}
return &snowflake.NextIdResp{Id: id}, nil
}
@@ -0,0 +1,37 @@
package logic
import (
"context"
"errors"
"juwan-backend/app/snowflake/rpc/internal/svc"
"juwan-backend/app/snowflake/rpc/snowflake"
"github.com/zeromicro/go-zero/core/logx"
)
type NextIdsLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewNextIdsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NextIdsLogic {
return &NextIdsLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *NextIdsLogic) NextIds(in *snowflake.NextIdsReq) (*snowflake.NextIdsResp, error) {
if in.Count <= 0 || in.Count > 1000 {
return nil, errors.New("count must be between 1 and 1000")
}
ids, err := l.svcCtx.Generator.NextIDs(int(in.Count))
if err != nil {
l.Errorf("generate snowflake ids failed: %v", err)
return nil, err
}
return &snowflake.NextIdsResp{Ids: ids}, nil
}
@@ -0,0 +1,94 @@
package generator
import (
"errors"
"sync"
"time"
)
const (
epoch = int64(1609459200000)
datacenterIdBits = uint(5)
workerIdBits = uint(5)
sequenceBits = uint(12)
maxDatacenterId = -1 ^ (-1 << datacenterIdBits)
maxWorkerId = -1 ^ (-1 << workerIdBits)
maxSequence = -1 ^ (-1 << sequenceBits)
workerIdShift = sequenceBits
datacenterIdShift = sequenceBits + workerIdBits
timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits
)
type Snowflake struct {
mu sync.Mutex
timestamp int64
datacenterId int64
workerId int64
sequence int64
}
func NewSnowflake(datacenterId, workerId int64) (*Snowflake, error) {
if datacenterId < 0 || datacenterId > maxDatacenterId {
return nil, errors.New("datacenter id must be between 0 and 31")
}
if workerId < 0 || workerId > maxWorkerId {
return nil, errors.New("worker id must be between 0 and 31")
}
return &Snowflake{
timestamp: 0,
datacenterId: datacenterId,
workerId: workerId,
sequence: 0,
}, nil
}
func (s *Snowflake) NextID() (int64, error) {
s.mu.Lock()
defer s.mu.Unlock()
now := time.Now().UnixMilli()
if now < s.timestamp {
return 0, errors.New("clock moved backwards")
}
if now == s.timestamp {
s.sequence = (s.sequence + 1) & maxSequence
if s.sequence == 0 {
for now <= s.timestamp {
now = time.Now().UnixMilli()
}
}
} else {
s.sequence = 0
}
s.timestamp = now
id := ((now - epoch) << timestampLeftShift) |
(s.datacenterId << datacenterIdShift) |
(s.workerId << workerIdShift) |
s.sequence
return id, nil
}
func (s *Snowflake) NextIDs(count int) ([]int64, error) {
if count <= 0 || count > 1000 {
return nil, errors.New("count must be between 1 and 1000")
}
ids := make([]int64, count)
for i := 0; i < count; i++ {
id, err := s.NextID()
if err != nil {
return nil, err
}
ids[i] = id
}
return ids, nil
}
@@ -0,0 +1,34 @@
// Code generated by goctl. DO NOT EDIT.
// goctl 1.9.2
// Source: snowflake.proto
package server
import (
"context"
"juwan-backend/app/snowflake/rpc/internal/logic"
"juwan-backend/app/snowflake/rpc/internal/svc"
"juwan-backend/app/snowflake/rpc/snowflake"
)
type SnowflakeServiceServer struct {
svcCtx *svc.ServiceContext
snowflake.UnimplementedSnowflakeServiceServer
}
func NewSnowflakeServiceServer(svcCtx *svc.ServiceContext) *SnowflakeServiceServer {
return &SnowflakeServiceServer{
svcCtx: svcCtx,
}
}
func (s *SnowflakeServiceServer) NextId(ctx context.Context, in *snowflake.NextIdReq) (*snowflake.NextIdResp, error) {
l := logic.NewNextIdLogic(ctx, s.svcCtx)
return l.NextId(in)
}
func (s *SnowflakeServiceServer) NextIds(ctx context.Context, in *snowflake.NextIdsReq) (*snowflake.NextIdsResp, error) {
l := logic.NewNextIdsLogic(ctx, s.svcCtx)
return l.NextIds(in)
}
@@ -0,0 +1,25 @@
package svc
import (
"juwan-backend/app/snowflake/rpc/internal/config"
generator "juwan-backend/app/snowflake/rpc/internal/pkg"
)
type ServiceContext struct {
Config config.Config
Generator *generator.Snowflake
}
func NewServiceContext(c config.Config) *ServiceContext {
gen, err := generator.NewSnowflake(
c.Snowflake.DatacenterId,
c.Snowflake.WorkerId,
)
if err != nil {
panic(err)
}
return &ServiceContext{
Config: c,
Generator: gen,
}
}