golang 生成 slug 字符串

slug 介绍 slug 在不同的场景有不同的意义,在 URL 中表示一种用于描述资源的短简洁易于理解的资源描述符,在数据库系统中还可以用于描述资源的唯一标识符,总的来说 slug 可以用来标识和描述资源的文本标识符,有很好的可读性和唯一性。 本文将介绍 golang 中如何根据字符串生成相应的 slug 文本。 安装 执行 go get -u github.com/gosimple/slug 来安装 slug 使用 先介绍 slug 库的基础使用方法: package main import ( "fmt" "github.com/gosimple/slug" ) func main() { text := slug.Make("overstarry home") fmt.Println(text) text = slug.Make("text generate") fmt.Println(text) } 运行后: overstarry-home text-generate 除了基础的转换功能,slug 还支持将不同的语言进行转换,查看下面的例子: func main() { text := slug.Make("overstarry home") fmt.Println(text) text = slug.Make("text generate") fmt.Println(text) text = slug.Make("Hellö Wörld хелло ворлд") fmt.Println(text) someText := slug.Make("影師") fmt.Println(someText) enText := slug.MakeLang("This & that", "en") fmt.Println(enText) } overstarry-home text-generate hello-world-khello-vorld ping-guo this-and-that 如果想要保留大写字母,可以设置 slug.Lowercase 参数来实现。如果想实现自定义的替换可以使用 slug.CustomSub 来实现。 ...

五月 25, 2024 · overstarry

metabase 介绍及简单使用

前言 前面的文章介绍过一个开源的大数据可视化工具 - Apache Superset,本文将介绍作者最近了解到的另一个可视化工具 Metabase 。 Metabase 介绍 Metabase 是一个简单易用的开源项目,旨在为公司中的每个人提供商业智能和分析的最简单、最快捷的方法。Metabase具有以下核心优势和主要功能: 短时间内完成设置。 团队成员不需要 SQL 知识基础。 提供 SQL 编辑器来进行更复杂的查询。 构建漂亮、交互式的仪表盘,包括过滤器、自动刷新、全屏显示和自定义点击行为等功能。 定义规范的细分和指标供团队使用 使用仪表板订阅按计划将数据发送到 Slack 或发送电子邮件。 设置警报,让数据更改时通知您。 在应用程序中嵌入图表及仪表盘。 配置了细粒度的数据权限功能,方便进行数据安全控制。 安装 接下来介绍如何安装 Metabase,我们将使用 docker 部署的方式进行安装。 docker-compose.yaml内容如下: version: '3.9' services: metabase: image: metabase/metabase:latest container_name: metabase hostname: metabase volumes: - /dev/urandom:/dev/random:ro ports: - 3000:3000 environment: MB_DB_TYPE: postgres MB_DB_DBNAME: metabaseappdb MB_DB_PORT: 5432 MB_DB_USER: metabase MB_DB_PASS: mysecretpassword MB_DB_HOST: postgres networks: - metanet1 healthcheck: test: curl --fail -I http://localhost:3000/api/health || exit 1 interval: 15s timeout: 5s retries: 5 postgres: image: postgres:latest container_name: postgres hostname: postgres environment: POSTGRES_USER: metabase POSTGRES_DB: metabaseappdb POSTGRES_PASSWORD: mysecretpassword networks: - metanet1 networks: metanet1: driver: bridge 执行 docker compose up -d即可启动服务。接下来访问 http://127.0.0.1:3000/ 进行安装,设置完语言密码默认数据库,安装即算完成。 ...

五月 17, 2024 · overstarry

Go 生成 Google analytics 衡量ID

Google Analytics 介绍 Google Analytics(分析)4 是一项分析服务,用于衡量您的网站和应用中的流量和互动情况。本文将介绍如何通过调用 Google Analytics admin API来生成 Google Analytics 衡量ID. 配置 启用API 在 Google Cloud console 后台 API 和服务 启用 Google Analytics Admin API。 配置服务账号 为了调用API,我们需要创建一个服务账号,然后为创建的服务账号添加密钥。 需要注意的是还需要在 Google Analytics 为服务账号添加权限,不然请求接口会没数据。 安装 go客户端 接下来安装go客户端: go get google.golang.org/api/analyticsadmin/v1alpha 生成流程 接下来我们会按照常规的 id 生成流程编写相应的代码,流程: 1 获取账号信息 通过 List 接口获取当前服务账号所拥有的所有 Google Analytics 账户信息。 accountsService := analyticsadmin.NewAccountsService(service) accountsReply, err := accountsService.List().Do(); if err != nil { log.Fatal("list account err",err) return } for _,acc := range accountsReply.Accounts { fmt.Println(acc.Name) } 2 创建媒体资源 ...

四月 18, 2024 · overstarry

docker init 命令

前言 Docker 是一个广受欢迎的开发平台,它允许用户通过容器化技术来构建、打包和部署应用程序。尽管 Docker 提供了强大的功能和灵活性,但对于初学者而言,在项目中配置 Docker 可能会遇到一些挑战。 不过,Docker 官方为了降低使用门槛,推出了一个便捷的命令docker init。这个命令旨在快速初始化 Docker 配置,从而简化将 Docker 集成到项目中的流程。通过使用这个命令,用户可以轻松地为项目设置必要的 Docker 支持,进而享受到 Docker 带来的便利和效率提升。 docker init 简介 docker init 命令会根据用户指定的选项生成运行容器的一些文件,极大的加快了项目的容器化: .dockerignore : docker 构建时忽略的文件列表 Dockerfile: 镜像的核心文件 Compose.yaml: docker compose 的配置文件 README.Docker.md 如果你的项目中已有以上文件,会让你选择是否覆盖旧文件避免文件冲突问题。 docker init 提供了一组项目的模板文件,包括了 Go、Python、ASP.NET Core等常见的服务器应用程序及一个其它类型应用程序模板。开发者使用 init 命令时,可以根据选择的模板生成相应的文件,使开发者可以快速的构建并启动容器。 使用 接下来介绍如何使用 docker init 进行项目容器的初始化,这里以前文的go项目为例子进行介绍。 进入项目根目录执行 init 命令,选择go模板,会让你选择使用的go版本,主程序的位置及应用所使用的端口: 执行完可以看到会生成相应的文件及如何构建并运行的命令。 查看生成的Dockerfile 和 Compose.yaml文件: # syntax=docker/dockerfile:1 # Comments are provided throughout this file to help you get started. # If you need more help, visit the Dockerfile reference guide at # https://docs.docker.com/go/dockerfile-reference/ # Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7 ################################################################################ # Create a stage for building the application. ARG GO_VERSION=1.21.0 FROM --platform=$BUILDPLATFORM golang:${GO_VERSION} AS build WORKDIR /src # Download dependencies as a separate step to take advantage of Docker's caching. # Leverage a cache mount to /go/pkg/mod/ to speed up subsequent builds. # Leverage bind mounts to go.sum and go.mod to avoid having to copy them into # the container. RUN --mount=type=cache,target=/go/pkg/mod/ \ --mount=type=bind,source=go.sum,target=go.sum \ --mount=type=bind,source=go.mod,target=go.mod \ go mod download -x # This is the architecture you’re building for, which is passed in by the builder. # Placing it here allows the previous steps to be cached across architectures. ARG TARGETARCH # Build the application. # Leverage a cache mount to /go/pkg/mod/ to speed up subsequent builds. # Leverage a bind mount to the current directory to avoid having to copy the # source code into the container. RUN --mount=type=cache,target=/go/pkg/mod/ \ --mount=type=bind,target=. \ CGO_ENABLED=0 GOARCH=$TARGETARCH go build -o /bin/server ./retry/server ################################################################################ # Create a new stage for running the application that contains the minimal # runtime dependencies for the application. This often uses a different base # image from the build stage where the necessary files are copied from the build # stage. # # The example below uses the alpine image as the foundation for running the app. # By specifying the "latest" tag, it will also use whatever happens to be the # most recent version of that image when you build your Dockerfile. If # reproducability is important, consider using a versioned tag # (e.g., alpine:3.17.2) or SHA (e.g., alpine@sha256:c41ab5c992deb4fe7e5da09f67a8804a46bd0592bfdf0b1847dde0e0889d2bff). FROM alpine:latest AS final # Install any runtime dependencies that are needed to run your application. # Leverage a cache mount to /var/cache/apk/ to speed up subsequent builds. RUN --mount=type=cache,target=/var/cache/apk \ apk --update add \ ca-certificates \ tzdata \ && \ update-ca-certificates # Create a non-privileged user that the app will run under. # See https://docs.docker.com/go/dockerfile-user-best-practices/ ARG UID=10001 RUN adduser \ --disabled-password \ --gecos "" \ --home "/nonexistent" \ --shell "/sbin/nologin" \ --no-create-home \ --uid "${UID}" \ appuser USER appuser # Copy the executable from the "build" stage. COPY --from=build /bin/server /bin/ # Expose the port that the application listens on. EXPOSE 9000 # What the container should run when it is started. ENTRYPOINT [ "/bin/server" ] 可以看到 Dockerfile 是一个常见的多阶段构建镜像流程。 ...

四月 13, 2024 · overstarry

gRPC客户端负载均衡

gRPC 中的负载均衡包括服务端负载均衡和客户端负载均衡,本文将介绍客户端负载均衡,gRPC中的客户端负载均衡主要有2个部分:1) Name Resolver 2) Load Balancing Policy 接下来将依次介绍。 Name Resolver gRPC 中的默认 name-system 是 DNS , 同时各种客户端还提供了插件以使用自定义 name-system。gRPC Name Resolver 会根据 name-system 进行对应的解析,将用户提供的名称转换为对应的地址。 Load Balancing Policy gRPC 中内置了多种负载均衡策略,本文将介绍常见的几种负载均衡策略:1) pick_first 2) round_robin pick_first pick_first 是默认的负载均衡策略,该策略从 Name Resolver 获得到服务器的地址列表,按顺序依次对每个服务器地址进行连接,直到连接成功,如果某个地址连接成功则所有的RPC请求都会发送到这个服务器地址。 round_robin round_robin 策略,该策略从 Name Resolver 获得到服务器的地址列表,依次将请求发送到每一个地址,例如第一个请求将发送到 backend1 ,第二个请求将发送到 backend2 。 接下来分别使用这两种策略进行测试。 例子 我们先创建服务端,循环创建了3个服务端,分别使用30051、30052、30053端口。 package main import ( "context" "fmt" "log" "net" "sync" "google.golang.org/grpc" pb "github.com/overstarry/grpc-example/proto/echo" ) var ( addrs = []string{":30051", ":30052",":30053"} ) type ecServer struct { pb.UnimplementedEchoServer addr string } func (s *ecServer) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { return &pb.EchoResponse{Message: fmt.Sprintf("%s (from %s)", req.Message, s.addr)}, nil } func startServer(addr string) { lis, err := net.Listen("tcp", addr) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterEchoServer(s, &ecServer{addr: addr}) log.Printf("serving on %s\n", addr) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } } func main() { var wg sync.WaitGroup for _, addr := range addrs { wg.Add(1) go func(addr string) { defer wg.Done() startServer(addr) }(addr) } wg.Wait() } 接下来创建对应的客户端连接: ...

三月 30, 2024 · overstarry