01-常见编程语言-如何在命令行编译并运行

常见编程语言-如何在命令行编译并运行

1 : Summary

2 : java 编译与运行

2.1 环境准备

  • 环境准备 安装 oracle java sdk ,或者 oracle open jdk ,然后将 java 可执行程序所在程序配置到 $PATH (windows 用户配置到 %path%)。
  • java open jdk 有非常多的版本,可通过 jabba 安装,版本非常全。 windows 用户安装了 scoop 的,可以使用 scoop 来安装,使用 scoop search jdk 会提示相应的步骤 macos/linux 用户还可以使用 jenv 来管理多版本。

2.2 编写代码

1
2
3
4
5
6
// hello.java
class Hello {
  public static void main(String[] args){
    System.out.println("I'm a Simple Program");
  }
}

2.3 编译运行

  • 命令javac hello.java && java Hello

Go项目一般性组织结构

Go项目一般性组织结构

1: summary

2: 其他一些规划方案

3: 自己的规划组织方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
├── cmd/
   └── main.go //启动函数
├── server                 // 对外的服务,比如微服务,rpc
   └── rpc
   └── micro
├── pkg
    ├── common  // 全局
       └── conf
       └── log
       └── db
       └── redis
       └── globalvaribal
       └── const
    ├── internal/
           └── service/
               └── xxx_service.go //业务逻辑处理类
               └── xxx_service_test.go
           └── model/
               └── xxx_info.go//结构体
           └── api/
               └── xxx_api.go//路由对应的接口实现
           └── router/
               └── router.go//路由
           └── tools/   // 服务内部的一些公共工具,方法和函数
               └── datetool//时间工具类
               └── jsontool//json 工具类

01-ClickHouse常用sql脚本

ClickHouse常用sql脚本

一: ClickHouse 介绍

  • ClickHouse 是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS).
  • https://clickhouse.com/docs/zh/
  • 数据文件路径: /var/lib/clickhouse/
  • 日志文件路径:/var/log/clickhouse-server/clickhouse-server.log

二: Clickhouse 连接

三: ClickHouse Database

3.1 数据库操作

  • ClickHouse 严格区分大小写
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
-- 显示所有数据库
SHOW database

-- 显示当前使用的数据库
select currentDatabase();

-- 创建数据库
CREATE database if not exists tick

-- 删除数据库
DROP  database tick ON CLUSTER <集群名>

-- 显示数据库中的所有表
show tables FROM tick ON CLUSTER <集群名>

-- 手动optimize,合并分区
optimize table tick final;

3.2 表操作

3.2.1 查看表结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
-- 建表
create table IF NOT EXISTS test.user ON CLUSTER <集群名> (
    `uid` Int32,
    `name` String,
    `age` UInt32,
    `birthday` Date
)ENGINE = MergeTree()
PARTITION BY  (`birthday`)
ORDER BY (uid,birthday);

-- 设置表TTL
--    涉及判断的字段必须是Date或者Datetime类型,推荐使用分区的日期字段:
--      SECOND , MINUTE , HOUR , DAY , WEEK , MONTH , QUARTER , YEAR
Alter table test.user Modify TTL createAt+interval 1 day;


-- 显示表结构
DESCRIBE TABLE test.user;

-- 显示建表语句
SHOW CREATE TABLE test.user;

-- 删除表
DROP table IF EXISTS test.student;

-- 添加字段
alter table product_test add column `test` String DEFAULT '' COMMENT '注释';

--删除字段
alter table product_test drop column `test`;

--修改字段
alter table product_test modify column `test` Nullable(String) DEFAULT NULL COMMENT '注释';

--删除数据
ALTER TABLE db_name.table_name DROP PARTITION '分区(例如:时间20220516)'

-- 删除表中所有数据(清空表)
alter table tableName delete where 1=1;

四: View 视图

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
--ClickHouse支持视图功能,目前一共支持两种视图:普通(Normal)视图和物化(Materialized)视图
--通过DROP TABLE [$db_name.]$view_table_name语句可以直接删除视图,而通过SHOW TABLES可以展示所有的表,视图也会被认为是一种特殊的表一并进行展示

--普通视图
--普通视图不会存储任何数据,它只是一个查询映射,起到了简化查询语义的作用,对查询的性能也不会有任何正负作用


--物化视图
--物化视图支持定义表引擎,因为其数据保存的形式由表引擎决定
--需要定义表引擎,决定数据存储的形式
--物化视图中的数据不支持同步删除,如果源表的数据不存在或者源表被删除了,物化视图的数据依然存在
--物化视图不会随着基础表的变化而变化,所以它也称为快照(snapshot)
--如果要更新数据的话,需要用户手动进行,如周期性执行SQL,或利用触发器等机制

五: ClickHouse-client

1
2
3
4
5
//
clickhouse-client --host localhost --user admin --password admin

// 导出数据
clickhouse-client --query "select * from t_order_mt where create_time='2020-06-01 12:00:00'" --format CSVWithNames> /opt/module/data/rs1.csv

六: clickhouse-local

01-docker cheat sheet

Docker Cheat Sheet

1: Process Management

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Show all running docker containers
docker ps
# Show all docker containers
docker ps -a
# Run a container
docker run <image>:<tag>
# Run a container and connect to it
docker run -it <image>:<tag>
# Run a container in the background
docker run -d <image>:<tag>
# Stop a container
docker stop <container>
# Kill a container
docker kill <container>

2: Images/Repository

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# List available local images
docker images
# Search for docker images
docker search <image>
# Pull a docker image
docker pull <image>
# Build an image with a dockerfile
docker build -t <image>:<tag> <run_directory> -f <dockerfile>
# Login to a remote repository
docker login <repository>
# Push an image to your remotee repository
docker push <image>:<tag>
# Remove a local docker image
docker rmi <image>:<tag>
# Show metadata for an image
docker inspect <image>
# Remove all unused docker images
docker image prune

3: Volumes & Ports

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# List volumes
docker volume ls
# Create a volume
docker volume create <volume>
# Delete a volume
docker volume rm <volume>
# Show volume metadata
docker volume inspect <volume>
# Delete all volumes not attached to a container
docker volume prune
# Mount a local directory to your container
docker run -v <local_dir>:<container_dir> <image>
# Copy file or folder from a docker container to host machine
docker cp <container>:<container_dir> <local_dir>
# Copy file or folder from local machine onto a container
docker cp <local_dir> <container>:<container_dir>
# Map a local port to a docker instance
docker run -d -p 127.0.0.1:<local_port>:<docker_port> <image>
# List the ports a docker container is running on
docker port <container>

4: Troubleshooting(故障排除)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Show the logs of a container
docker logs <container>
# Follow/tail the logs of a container
docker logs -f <container>
# Show timestamps on docker logs
docker logs -t <container>
# Show details/metadata of a container
docker inspect <container>
# Show a 'top' view of processes running on a container
docker top <container>
# Show a 'top' view of all docker containers
docker stats
# Show any files that have changed since startup
docker diff <container>
# Connect to an already running container
docker attach <container>
# Execute a command on a container
docker exec -it <container_id> /bin/bash
# Show docker system wide information
docker system info
# Show docker disk space used
docker system df

5: Docker Compose

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Start your docker-compose defined resources in detached mode
docker-compose up -d -f <docker_compose_yaml>
# Stop all docker-compose resources
docker-compose stop
# Destroy all docker-compose resources
docker-compose down
# Show docker-compose processes
docker-compose ps
# Show docker-compose logs
docker-compose logs
# Show docker-compose resource consumption
docker-compose top

01-docker-compose搭建redis cluster

docker-compose搭建redis cluster

一: Redis Cluster 集群

  • 在 Redis 中,集群的解决方案有三种
    • 1.主从复制
    • 2.哨兵机制
    • 3.Cluster

二: 主从复制模式

Redis 虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis 支持主从复制,读写分离。一个 Master 可以有多个 Slaves。 redis-master-slave复制模式

02-Go TestBenchmark

Go TestBenchmark笔记
Table of Contents =================

Go Test Benchmark

  • 在 Go 中,通过撰写 Benchmark 函数可以很方便地对某个功能点进行性能检测。对于重要的函数,我们可以在 CI/CD 中添加相应的测试流程,当函数性能发生变化时能够及时感知。那问题来了,如何检测函数的性能变化?
  • 换个说法,你编写了某功能函数但发现它运行很慢,需要对该函数进行优化,当你在谷歌搜索找到更好的实现方式,通过 Benchmark 函数发现它的确变快了。但你说不清楚具体变快了多少,你想知道函数优化前后的性能对比,提高多少百分点,可信度高吗?
  • 针对以上的需求场景,有一个工具可以帮助到你,它就是 benchstat

1.1 go test benchmark 示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// fib.go
func FibSolution(n int) int {
 if n < 2 {
  return n
 }

 return FibSolution(n-1) + FibSolution(n-2)
}

// fib_test.go
func BenchmarkFib20(b *testing.B) {
 for i := 0; i < b.N; i++ {
  FibSolution(20)
 }
}

// 命令行执行go test -bench=BenchmarkFib20得到性能结果

执行 go test -bench=BenchmarkFib20 得到性能结果:

01-消息队列Kafka和Pulsar选型

消息队列Kafka和Pulsar选型

Table of Contents

1: 业务场景

1.1 业务场景描述

  • 我们需要一个把实时的交易数据进行持久化保存,并且能快速的给其他服务提供最新的交易数据;
  • 当服务启动或者重启后,能快速提供完整的并且最新的交易数据;
  • 现有的机制是每个订单使用 go 协程直接写入 Mysql 数据库,对数据库的压力比较大,且系统的延迟比较高;

1.2 业务场景 feature

  • 解耦,降低数据数据库性能导致的整个服务延迟;
  • 数据完整的,及时地进行持久化;
  • 交易数据能,迅速的提供给其他需要数据的服务;
  • 流量消峰,减少峰值流量直接对数据库服务造成的冲击, 提高系统的稳定性;

2:消息中间件

  • 适合用消息中间件解决上述问题;
    • (1) 解耦: 将一个流程的上游和下游拆开,上游专注生产消息,下游专注处理消息;
    • (2) 广播: 一个上游生产的消息轻松被多个下游服务消费处理;
    • (3) 缓冲(流量削峰): 如果上游服务流量突然暴涨,mq 可以做一个缓冲器的作用,下游根据消费能力对消息进行消费,避免暴涨的流量直接对下游服务造成冲击;
    • (4) 异步: 生产者生产消息之后可以马上直接返回,消费者可以异步处理消息;
    • (5) 冗余: 保留历史消息,处理失败或者当出现异常的时候可以进行重试或者回溯,防止消息丢失。
  • 近几年出现了一些关注度较高的消息队列中间件选型,如 Kafka、Pulsar、RocketMQ 等,首先从宏观上做一些对比:
    常见MQ对比
    MQ特性描述KafkaPulsarRocketMQRabbitMQNSQ我们的业务场景是否需要
    推出时间2012 年(Scala 和 Java)2016 年(Java)2012 年(Java)2007 年(Erlang)2013 年(Go)
    组织Linkin 开源,ApacheYahoo 开源,Apache阿里开源,ApachePivotal 开源,MozillaMIT
    功能消费模式consumer消费消息的方式pullpushpullpushpush?
    延迟队列消息投递延迟NoYesYesYesYes
    死信队列NoYesYesYesNo?
    优先级队列NoNoNoYesNo
    消息回溯YesYesYesNoNo需要
    消息持久化YesYesYesYesYes需要
    消息确认机制offsetoffset+单条offset单条单条需要
    消息TTL消息TTL表示一条消息的生存时间,如果消息发出来后,在TTL的时间内没有消费者进行消费,消息队列会将消息删除或者放入死信队列中YesYesYesYesNo需要
    多租户隔离NoYesNoNoNo?
    消息顺序性消息顺序性是指保证消息有序。消息消费顺序跟生产的顺序保持一致分区有序stream模式有序consumer加锁NoNo?
    消息查询查看MQ中消息的内容,比如通过某个MessageKey/ID,查询到MQ的具体消息NoYesYesYesNo需要
    消费模式stream模式流模式+队列模式广播模式+集群模式队列模式队列模式需要,根据场景选择消费模式
    消息可靠性以生产的消息,发送到mq,防止丢失request.required.acksAck Quorum Size(Qa)RocketMQ与Kafka类似RabbitMQ是主从架构,通过镜像环形队列实现多副本及强一致性语义的NSQ会通过go-diskqueue组件将消息落盘到本地文件中,通过mem-queue-size参数控制内存中队列大小,如果mem-queue-size=0每条消息都会存储到磁盘里,不用担心节点重启引起的消息丢失。但由于是存储在本地磁盘中,如果节点离线,堆积在节点磁盘里的消息会丢失非常重要
    性能单机吞吐量605MB/S605MB/S大概500MB/S38MB/S?重要
    消息延迟5ms5msms级us级非常重要
    支持Topics数百~千,过多会影响性能百万个百~千几千?
    运维与可靠性高可用分布式架构分布式架构Master/SlaveMaster/Slave分布式架构非常重要
    集群扩容增加node,node之间会复制数据均衡增加node,通过新增加分片进行负载均衡增加节点增加节点增加节点
    异地容灾

3: Kafka 特性

4: Pulsar 特性

5: Kafka 和 Pulsar 对比

01-git仓库gomod私有化

git仓库gomod私有化

1: go module 私有仓库使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
(1) 修改hosts
(2)
go env -w GOINSECURE="gitlab.yuliangtec.cn"
go env -w GONOSUMDB="gitlab.yuliangtec.cn"
go env -w GONOPROXY="gitlab.yuliangtec.cn"
go env -w GOPRIVATE="gitlab.yuliangtec.cn"

// (3) go get
go get com.yuliangtec.luna.proto


// (4) git tag --> go get
go get com.yuliangtec.luna.proto@v1.0.0

2: 补充

2.1 协议

2.2 设置环境变量(上 1)

https://blog.csdn.net/L_K1028/article/details/105313293

02-GRPC_Makefile

GRPC Makefile脚本
  • Makefile文件内容如下:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

GOPATH:=$(shell go env GOPATH)
VERSION=$(shell git describe --tags --always)
INTERNAL_PROTO_FILES=$(shell find internal -name *.proto)
API_PROTO_FILES=$(shell find proto -name *.proto)



.PHONY: init
# init env
init:
	go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
	go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
	go install go.unistack.org/protoc-gen-go-micro/v3@latest
	go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway@latest
	go install github.com/google/gnostic/cmd/protoc-gen-openapi@latest


.PHONY: config
# generate internal proto

.PHONY: api
# generate api proto
api:
	protoc --proto_path=. \
	       --proto_path=./third_party \
 	       --go_out=paths=import:. \
 	       --go-http_out=paths=import:. \
 	       --go-grpc_out=paths=import:. \
 	       --go-micro_out=debug=true,,components="micro",paths=import:. \
	       $(API_PROTO_FILES)

 	    #    --go-micro_out=debug=true,,components="micro|http",paths=source_relative:./go_proto
		#    --openapi_out==paths=source_relative:./go_proto
		#    --swagger_out=logtostderr=true:./go_proto

.PHONY: clean
# rm -rf "./go_proto/pb"
clean:
	find ./go_proto -name "*.pb.go" | xargs rm -f

.PHONY: build
# build
build:
	mkdir -p bin/ && go build -ldflags "-X main.Version=$(VERSION)" -o ./bin/ ./...

.PHONY: generate
# generate
generate:
	go generate ./...

.PHONY: all
# generate all
all:
	make api;
	# make generate;

.PHONY: help
# show help
help:
	@echo ''
	@echo 'Usage:'
	@echo ' make [target]'
	@echo ''
	@echo 'Targets:'
	@awk '/^[a-zA-Z\-\_0-9]+:/ { \
	helpMessage = match(lastLine, /^# (.*)/); \
		if (helpMessage) { \
			helpCommand = substr($$1, 0, index($$1, ":")-1); \
			helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
			printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
		} \
	} \
	{ lastLine = $$0 }' $(MAKEFILE_LIST)

.DEFAULT_GOAL := help

01-Go Dockerfile

Go Dockerfile模板

1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
FROM golang:alpine AS builder

LABEL stage=gobuilder

ENV CGO_ENABLED 0
ENV GOOS linux
ENV GOPROXY https://goproxy.cn,direct

WORKDIR /build

ADD go.mod .
ADD go.sum .
RUN go mod download
COPY . .
RUN go build -ldflags="-s -w" -o /app/hello ./hello.go


FROM alpine

RUN apk update --no-cache && apk add --no-cache ca-certificates tzdata
ENV TZ Asia/Shanghai

WORKDIR /app
COPY --from=builder /app/hello /app/hello

CMD ["./hello"]

2: 说明

  • 默认禁用了 cgo
  • 启用了 GOPROXY
  • 去掉了调试信息 -ldflags="-s -w" 以减小镜像尺寸
  • 安装了 ca-certificates,这样使用 TLS 证书就没问题了
  • 自动设置了本地时区,这样我们在日志里看到的是北京时间了