dxc vor 1 Jahr
Commit
7f3680585c

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 9 - 0
.idea/generateid.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/generateid.iml" filepath="$PROJECT_DIR$/.idea/generateid.iml" />
+    </modules>
+  </component>
+</project>

+ 26 - 0
api/generateid.api

@@ -0,0 +1,26 @@
+syntax = "v1"
+
+info(
+	title: "generate id"
+	desc: "Using the snowflake algorithm, generate a 64-bit non-repeating number"
+	author: "dxc"
+	email: ""
+	version: "1.0.0"
+)
+
+type response {
+	Id        int64 `json:"id"`
+	NodeId    int64 `json:"node_id"`
+	Timestamp int64 `json:"timestamp"`
+}
+
+@server(
+	//    jwt: Auth
+	group: v1
+	timeout: 3s
+)
+
+service generate {
+	@handler generate
+	get /generate/id returns (response)
+}

+ 5 - 0
etc/generate.yaml

@@ -0,0 +1,5 @@
+Name: generate
+Host: 0.0.0.0
+Port: 8888
+
+Node: 1

+ 31 - 0
generate.go

@@ -0,0 +1,31 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+
+	"generateid/internal/config"
+	"generateid/internal/handler"
+	"generateid/internal/svc"
+
+	"github.com/zeromicro/go-zero/core/conf"
+	"github.com/zeromicro/go-zero/rest"
+)
+
+var configFile = flag.String("f", "etc/generate.yaml", "the config file")
+
+func main() {
+	flag.Parse()
+
+	var c config.Config
+	conf.MustLoad(*configFile, &c)
+
+	server := rest.MustNewServer(c.RestConf)
+	defer server.Stop()
+
+	ctx := svc.NewServiceContext(c)
+	handler.RegisterHandlers(server, ctx)
+
+	fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
+	server.Start()
+}

+ 47 - 0
go.mod

@@ -0,0 +1,47 @@
+module generateid
+
+go 1.20
+
+require github.com/zeromicro/go-zero v1.6.6
+
+require (
+	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
+	github.com/cespare/xxhash/v2 v2.2.0 // indirect
+	github.com/fatih/color v1.17.0 // indirect
+	github.com/go-logr/logr v1.3.0 // indirect
+	github.com/go-logr/stdr v1.2.2 // indirect
+	github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
+	github.com/google/uuid v1.6.0 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect
+	github.com/mattn/go-colorable v0.1.13 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
+	github.com/openzipkin/zipkin-go v0.4.2 // indirect
+	github.com/pelletier/go-toml/v2 v2.2.2 // indirect
+	github.com/prometheus/client_golang v1.18.0 // indirect
+	github.com/prometheus/client_model v0.5.0 // indirect
+	github.com/prometheus/common v0.45.0 // indirect
+	github.com/prometheus/procfs v0.12.0 // indirect
+	github.com/spaolacci/murmur3 v1.1.0 // indirect
+	go.opentelemetry.io/otel v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/zipkin v1.19.0 // indirect
+	go.opentelemetry.io/otel/metric v1.19.0 // indirect
+	go.opentelemetry.io/otel/sdk v1.19.0 // indirect
+	go.opentelemetry.io/otel/trace v1.19.0 // indirect
+	go.opentelemetry.io/proto/otlp v1.0.0 // indirect
+	go.uber.org/automaxprocs v1.5.3 // indirect
+	golang.org/x/net v0.26.0 // indirect
+	golang.org/x/sys v0.21.0 // indirect
+	golang.org/x/text v0.16.0 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
+	google.golang.org/grpc v1.64.0 // indirect
+	google.golang.org/protobuf v1.34.2 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
+)

+ 114 - 0
go.sum

@@ -0,0 +1,114 @@
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
+github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
+github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
+github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
+github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk=
+github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
+github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
+github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDOCg/jA=
+github.com/openzipkin/zipkin-go v0.4.2/go.mod h1:ZeVkFjuuBiSy13y8vpSDCjMi9GoI3hPpCJSBx/EYFhY=
+github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
+github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
+github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
+github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
+github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
+github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
+github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
+github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
+github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
+github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
+github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
+github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
+github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/zeromicro/go-zero v1.6.6 h1:nZTVYObklHiBdYJ/nPoAZ8kGVAplWSDjT7DGE7ur0uk=
+github.com/zeromicro/go-zero v1.6.6/go.mod h1:olKf1/hELbSmuIgLgJeoeNVp3tCbLqj6UmO7ATSta4A=
+go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
+go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
+go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
+go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
+go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0 h1:Nw7Dv4lwvGrI68+wULbcq7su9K2cebeCUrDjVrUJHxM=
+go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0/go.mod h1:1MsF6Y7gTqosgoZvHlzcaaM8DIMNZgJh87ykokoNH7Y=
+go.opentelemetry.io/otel/exporters/zipkin v1.19.0 h1:EGY0h5mGliP9o/nIkVuLI0vRiQqmsYOcbwCuotksO1o=
+go.opentelemetry.io/otel/exporters/zipkin v1.19.0/go.mod h1:JQgTGJP11yi3o4GHzIWYodhPisxANdqxF1eHwDSnJrI=
+go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
+go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
+go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
+go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
+go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
+go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
+go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
+go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
+go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
+go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
+go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
+golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
+golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
+golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
+golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4=
+google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
+google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
+google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
+google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
+google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=

+ 8 - 0
internal/config/config.go

@@ -0,0 +1,8 @@
+package config
+
+import "github.com/zeromicro/go-zero/rest"
+
+type Config struct {
+	rest.RestConf
+	Node int64
+}

+ 25 - 0
internal/handler/routes.go

@@ -0,0 +1,25 @@
+// Code generated by goctl. DO NOT EDIT.
+package handler
+
+import (
+	"net/http"
+	"time"
+
+	v1 "generateid/internal/handler/v1"
+	"generateid/internal/svc"
+
+	"github.com/zeromicro/go-zero/rest"
+)
+
+func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
+	server.AddRoutes(
+		[]rest.Route{
+			{
+				Method:  http.MethodGet,
+				Path:    "/generate/id",
+				Handler: v1.GenerateHandler(serverCtx),
+			},
+		},
+		rest.WithTimeout(3000*time.Millisecond),
+	)
+}

+ 21 - 0
internal/handler/v1/generatehandler.go

@@ -0,0 +1,21 @@
+package v1
+
+import (
+	"net/http"
+
+	"generateid/internal/logic/v1"
+	"generateid/internal/svc"
+	"github.com/zeromicro/go-zero/rest/httpx"
+)
+
+func GenerateHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		l := v1.NewGenerateLogic(r.Context(), svcCtx)
+		resp, err := l.Generate()
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 34 - 0
internal/logic/v1/generatelogic.go

@@ -0,0 +1,34 @@
+package v1
+
+import (
+	"context"
+	"time"
+
+	"generateid/internal/svc"
+	"generateid/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type GenerateLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGenerateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GenerateLogic {
+	return &GenerateLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx,
+	}
+}
+
+func (l *GenerateLogic) Generate() (resp *types.Response, err error) {
+	resp = &types.Response{
+		Id:        l.svcCtx.Node.Generate().Int64(),
+		NodeId:    l.svcCtx.Config.Node,
+		Timestamp: time.Now().Unix(),
+	}
+	return
+}

+ 22 - 0
internal/svc/servicecontext.go

@@ -0,0 +1,22 @@
+package svc
+
+import (
+	"generateid/internal/config"
+	snowflake "generateid/pkg/sonwflake"
+)
+
+type ServiceContext struct {
+	Config config.Config
+	Node   *snowflake.Node
+}
+
+func NewServiceContext(c config.Config) *ServiceContext {
+	node, err := snowflake.NewNode(c.Node)
+	if err != nil {
+		panic(err)
+	}
+	return &ServiceContext{
+		Config: c,
+		Node:   node,
+	}
+}

+ 8 - 0
internal/types/types.go

@@ -0,0 +1,8 @@
+// Code generated by goctl. DO NOT EDIT.
+package types
+
+type Response struct {
+	Id        int64 `json:"id"`
+	NodeId    int64 `json:"node_id"`
+	Timestamp int64 `json:"timestamp"`
+}

+ 382 - 0
pkg/sonwflake/snowflake.go

@@ -0,0 +1,382 @@
+// Package snowflake provides a very simple Twitter snowflake generator and parser.
+package snowflake
+
+import (
+	"encoding/base64"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"strconv"
+	"sync"
+	"time"
+)
+
+var (
+	// Epoch is set to the twitter snowflake epoch of Nov 04 2010 01:42:54 UTC in milliseconds
+	// You may customize this to set a different epoch for your application.
+	Epoch int64 = 1704038400000 //2024-01-01 00:00:00
+
+	// NodeBits holds the number of bits to use for Node
+	// Remember, you have a total 22 bits to share between Node/Step
+	NodeBits uint8 = 10
+
+	// StepBits holds the number of bits to use for Step
+	// Remember, you have a total 22 bits to share between Node/Step
+	StepBits uint8 = 12
+
+	// DEPRECATED: the below four variables will be removed in a future release.
+	mu        sync.Mutex
+	nodeMax   int64 = -1 ^ (-1 << NodeBits)
+	nodeMask        = nodeMax << StepBits
+	stepMask  int64 = -1 ^ (-1 << StepBits)
+	timeShift       = NodeBits + StepBits
+	nodeShift       = StepBits
+)
+
+const encodeBase32Map = "ybndrfg8ejkmcpqxot1uwisza345h769"
+
+var decodeBase32Map [256]byte
+
+const encodeBase58Map = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
+
+var decodeBase58Map [256]byte
+
+// A JSONSyntaxError is returned from UnmarshalJSON if an invalid ID is provided.
+type JSONSyntaxError struct{ original []byte }
+
+func (j JSONSyntaxError) Error() string {
+	return fmt.Sprintf("invalid snowflake ID %q", string(j.original))
+}
+
+// ErrInvalidBase58 is returned by ParseBase58 when given an invalid []byte
+var ErrInvalidBase58 = errors.New("invalid base58")
+
+// ErrInvalidBase32 is returned by ParseBase32 when given an invalid []byte
+var ErrInvalidBase32 = errors.New("invalid base32")
+
+// Create maps for decoding Base58/Base32.
+// This speeds up the process tremendously.
+func init() {
+
+	for i := 0; i < len(decodeBase58Map); i++ {
+		decodeBase58Map[i] = 0xFF
+	}
+
+	for i := 0; i < len(encodeBase58Map); i++ {
+		decodeBase58Map[encodeBase58Map[i]] = byte(i)
+	}
+
+	for i := 0; i < len(decodeBase32Map); i++ {
+		decodeBase32Map[i] = 0xFF
+	}
+
+	for i := 0; i < len(encodeBase32Map); i++ {
+		decodeBase32Map[encodeBase32Map[i]] = byte(i)
+	}
+}
+
+// A Node struct holds the basic information needed for a snowflake generator
+// node
+type Node struct {
+	mu    sync.Mutex
+	epoch time.Time
+	time  int64
+	node  int64
+	step  int64
+
+	nodeMax   int64
+	nodeMask  int64
+	stepMask  int64
+	timeShift uint8
+	nodeShift uint8
+}
+
+// An ID is a custom type used for a snowflake ID.  This is used so we can
+// attach methods onto the ID.
+type ID int64
+
+// NewNode returns a new snowflake node that can be used to generate snowflake
+// IDs
+func NewNode(node int64) (*Node, error) {
+
+	if NodeBits+StepBits > 22 {
+		return nil, errors.New("Remember, you have a total 22 bits to share between Node/Step")
+	}
+	// re-calc in case custom NodeBits or StepBits were set
+	// DEPRECATED: the below block will be removed in a future release.
+	mu.Lock()
+	nodeMax = -1 ^ (-1 << NodeBits)
+	nodeMask = nodeMax << StepBits
+	stepMask = -1 ^ (-1 << StepBits)
+	timeShift = NodeBits + StepBits
+	nodeShift = StepBits
+	mu.Unlock()
+
+	n := Node{}
+	n.node = node
+	n.nodeMax = -1 ^ (-1 << NodeBits)
+	n.nodeMask = n.nodeMax << StepBits
+	n.stepMask = -1 ^ (-1 << StepBits)
+	n.timeShift = NodeBits + StepBits
+	n.nodeShift = StepBits
+
+	if n.node < 0 || n.node > n.nodeMax {
+		return nil, errors.New("Node number must be between 0 and " + strconv.FormatInt(n.nodeMax, 10))
+	}
+
+	var curTime = time.Now()
+	// add time.Duration to curTime to make sure we use the monotonic clock if available
+	n.epoch = curTime.Add(time.Unix(Epoch/1000, (Epoch%1000)*1000000).Sub(curTime))
+
+	return &n, nil
+}
+
+// Generate creates and returns a unique snowflake ID
+// To help guarantee uniqueness
+// - Make sure your system is keeping accurate system time
+// - Make sure you never have multiple nodes running with the same node ID
+func (n *Node) Generate() ID {
+
+	n.mu.Lock()
+	defer n.mu.Unlock()
+
+	now := time.Since(n.epoch).Milliseconds()
+
+	if now == n.time {
+		//同一毫秒生成,id+1
+		n.step = (n.step + 1) & n.stepMask
+		//等于零表示4096个号用完了
+		if n.step == 0 {
+			//方案1 从未来借时间
+			//now = now + 1
+			//方案2 等待下一毫秒
+			for now <= n.time {
+				now = time.Since(n.epoch).Milliseconds()
+			}
+		}
+	} else if now > n.time {
+		n.step = 0
+	} else {
+		//解决时钟回拨的问题
+		if n.time-now > 2000 {
+			fmt.Println("system time exception")
+		}
+		//不超过5秒,从未来借时间生成id
+		n.step = (n.step + 1) & n.stepMask
+		if n.step == 0 {
+			now = now + 1
+		}
+	}
+
+	n.time = now
+
+	r := ID((now)<<n.timeShift |
+		(n.node << n.nodeShift) |
+		(n.step),
+	)
+
+	return r
+}
+
+// Int64 returns an int64 of the snowflake ID
+func (f ID) Int64() int64 {
+	return int64(f)
+}
+
+// ParseInt64 converts an int64 into a snowflake ID
+func ParseInt64(id int64) ID {
+	return ID(id)
+}
+
+// String returns a string of the snowflake ID
+func (f ID) String() string {
+	return strconv.FormatInt(int64(f), 10)
+}
+
+// ParseString converts a string into a snowflake ID
+func ParseString(id string) (ID, error) {
+	i, err := strconv.ParseInt(id, 10, 64)
+	return ID(i), err
+
+}
+
+// Base2 returns a string base2 of the snowflake ID
+func (f ID) Base2() string {
+	return strconv.FormatInt(int64(f), 2)
+}
+
+// ParseBase2 converts a Base2 string into a snowflake ID
+func ParseBase2(id string) (ID, error) {
+	i, err := strconv.ParseInt(id, 2, 64)
+	return ID(i), err
+}
+
+// Base32 uses the z-base-32 character set but encodes and decodes similar
+// to base58, allowing it to create an even smaller result string.
+// NOTE: There are many different base32 implementations so becareful when
+// doing any interoperation.
+func (f ID) Base32() string {
+
+	if f < 32 {
+		return string(encodeBase32Map[f])
+	}
+
+	b := make([]byte, 0, 12)
+	for f >= 32 {
+		b = append(b, encodeBase32Map[f%32])
+		f /= 32
+	}
+	b = append(b, encodeBase32Map[f])
+
+	for x, y := 0, len(b)-1; x < y; x, y = x+1, y-1 {
+		b[x], b[y] = b[y], b[x]
+	}
+
+	return string(b)
+}
+
+// ParseBase32 parses a base32 []byte into a snowflake ID
+// NOTE: There are many different base32 implementations so becareful when
+// doing any interoperation.
+func ParseBase32(b []byte) (ID, error) {
+
+	var id int64
+
+	for i := range b {
+		if decodeBase32Map[b[i]] == 0xFF {
+			return -1, ErrInvalidBase32
+		}
+		id = id*32 + int64(decodeBase32Map[b[i]])
+	}
+
+	return ID(id), nil
+}
+
+// Base36 returns a base36 string of the snowflake ID
+func (f ID) Base36() string {
+	return strconv.FormatInt(int64(f), 36)
+}
+
+// ParseBase36 converts a Base36 string into a snowflake ID
+func ParseBase36(id string) (ID, error) {
+	i, err := strconv.ParseInt(id, 36, 64)
+	return ID(i), err
+}
+
+// Base58 returns a base58 string of the snowflake ID
+func (f ID) Base58() string {
+
+	if f < 58 {
+		return string(encodeBase58Map[f])
+	}
+
+	b := make([]byte, 0, 11)
+	for f >= 58 {
+		b = append(b, encodeBase58Map[f%58])
+		f /= 58
+	}
+	b = append(b, encodeBase58Map[f])
+
+	for x, y := 0, len(b)-1; x < y; x, y = x+1, y-1 {
+		b[x], b[y] = b[y], b[x]
+	}
+
+	return string(b)
+}
+
+// ParseBase58 parses a base58 []byte into a snowflake ID
+func ParseBase58(b []byte) (ID, error) {
+
+	var id int64
+
+	for i := range b {
+		if decodeBase58Map[b[i]] == 0xFF {
+			return -1, ErrInvalidBase58
+		}
+		id = id*58 + int64(decodeBase58Map[b[i]])
+	}
+
+	return ID(id), nil
+}
+
+// Base64 returns a base64 string of the snowflake ID
+func (f ID) Base64() string {
+	return base64.StdEncoding.EncodeToString(f.Bytes())
+}
+
+// ParseBase64 converts a base64 string into a snowflake ID
+func ParseBase64(id string) (ID, error) {
+	b, err := base64.StdEncoding.DecodeString(id)
+	if err != nil {
+		return -1, err
+	}
+	return ParseBytes(b)
+
+}
+
+// Bytes returns a byte slice of the snowflake ID
+func (f ID) Bytes() []byte {
+	return []byte(f.String())
+}
+
+// ParseBytes converts a byte slice into a snowflake ID
+func ParseBytes(id []byte) (ID, error) {
+	i, err := strconv.ParseInt(string(id), 10, 64)
+	return ID(i), err
+}
+
+// IntBytes returns an array of bytes of the snowflake ID, encoded as a
+// big endian integer.
+func (f ID) IntBytes() [8]byte {
+	var b [8]byte
+	binary.BigEndian.PutUint64(b[:], uint64(f))
+	return b
+}
+
+// ParseIntBytes converts an array of bytes encoded as big endian integer as
+// a snowflake ID
+func ParseIntBytes(id [8]byte) ID {
+	return ID(int64(binary.BigEndian.Uint64(id[:])))
+}
+
+// Time returns an int64 unix timestamp in milliseconds of the snowflake ID time
+// DEPRECATED: the below function will be removed in a future release.
+func (f ID) Time() int64 {
+	return (int64(f) >> timeShift) + Epoch
+}
+
+// Node returns an int64 of the snowflake ID node number
+// DEPRECATED: the below function will be removed in a future release.
+func (f ID) Node() int64 {
+	return int64(f) & nodeMask >> nodeShift
+}
+
+// Step returns an int64 of the snowflake step (or sequence) number
+// DEPRECATED: the below function will be removed in a future release.
+func (f ID) Step() int64 {
+	return int64(f) & stepMask
+}
+
+// MarshalJSON returns a json byte array string of the snowflake ID.
+func (f ID) MarshalJSON() ([]byte, error) {
+	buff := make([]byte, 0, 22)
+	buff = append(buff, '"')
+	buff = strconv.AppendInt(buff, int64(f), 10)
+	buff = append(buff, '"')
+	return buff, nil
+}
+
+// UnmarshalJSON converts a json byte array of a snowflake ID into an ID type.
+func (f *ID) UnmarshalJSON(b []byte) error {
+	if len(b) < 3 || b[0] != '"' || b[len(b)-1] != '"' {
+		return JSONSyntaxError{b}
+	}
+
+	i, err := strconv.ParseInt(string(b[1:len(b)-1]), 10, 64)
+	if err != nil {
+		return err
+	}
+
+	*f = ID(i)
+	return nil
+}

+ 29 - 0
pkg/sonwflake/snowflake_test.go

@@ -0,0 +1,29 @@
+package snowflake
+
+import (
+	"fmt"
+	"runtime"
+	"sync"
+	"testing"
+	"time"
+)
+
+func TestGenerateID(t *testing.T) {
+	now := time.Now()
+	node, _ := NewNode(1)
+	var wg sync.WaitGroup
+	fmt.Println(runtime.NumCPU())
+	wg.Add(runtime.NumCPU())
+	for i := 0; i < runtime.NumCPU(); i++ {
+		go func() {
+			for j := 0; j < 100000; j++ {
+				_ = node.Generate()
+				//id := node.Generate()
+				//fmt.Println(id)
+			}
+			wg.Done()
+		}()
+	}
+	wg.Wait()
+	fmt.Println(time.Since(now))
+}