自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(157)
  • 收藏
  • 关注

原创 面向猴子编程 记录一次alertmanager二次开发,追加告警方式

对alertmanager进行二次开发,追加新的告警

2023-02-20 22:11:16 378

原创 微服务学习笔记 DDD中的Repository

浅薄的了解ddd中的repository层,就是起到一个聚合的作用。他介于domain和dao层之间,相当于一个聚合dao数据的作用。比如说我一个查询需要先查cache,命中不到再去找dao,那我这个逻辑就可以放在repo层;又比如说我一个domain层需要一组数据,这个数据是从多个表拿的,那么我就也可以吧多个dao查出来的数据,在repo层聚合。...

2022-05-17 10:56:07 1058

原创 算法 整数拆分

func integerBreak(n int) int { // 定义dp[i]的含义为,将i切分成2到2个以上的正数,取大乘积 dp := make([]int,n+1) // 因为1无法切分,所以初始化dp[2]即可 dp[2] = 1 // i可以看做为 i-j 与 j 的和,所以结果可以有这两种情况 // (i-j)*j 代表i切为两个整数 // dp[i-j]*j 代表i切为三个或三个以上整数(因为dp[i-j]代表i-j切为两个或两个以上

2022-05-04 17:50:34 298

原创 算法 01背包问题

package bagProblemimport "fmt"func BagProblem1(weight, value []int, bagweight int) int { // 定义一个dp[i][j],表示将任意0-i物品放入包后,在包j重量时,包中的价值最大 // 初始化dp都为0 dp := make([][]int, len(weight)) for i := 0; i < len(weight); i++ { // 这里为bagweight+1,表示重量从0开始到b

2022-05-04 17:48:30 223

原创 面向猴子编程 利用断言判断自定义err的类型

type ErrNo1 struct { s string}func (e *ErrNo1) Error() string { return e.s}type ErrNo2 struct { s string}func (e *ErrNo2) Error() string { return e.s}type ErrNo3 struct { s string}func (e *ErrNo3) Error() string { return e.s}func m.

2022-03-01 10:15:17 107

原创 面向猴子编程 比较两个结构体并打印差异

type Data struct { Name string `tag:"姓名"` Age int8 `tag:"年龄"`}func main() { newData := &Data{ Name: "test", Age: 3, } oldData := &Data{ Name: "test", Age: 2, } diffAndWrite(oldData, newData)}func diffAndWrite(oldData, .

2022-02-15 17:36:27 238

原创 面向猴子编程 GO制作水印

参考网上的文章写了一个制作水印的包,支持文字水印以及图片水印,喜欢的点个赞~~package watermarkimport ( "github.com/golang/freetype" "go.uber.org/zap/buffer" "image" "image/color" "image/draw" "image/jpeg" "image/png" "io/ioutil" "os")const ( TopLeft int = iota TopRight Bottom

2022-01-07 14:10:01 425

原创 面向猴子编程 并发

本篇文章主要讲述的是多线程并发的基础原理以及一些并发场景下如何解决并发带来的共享数据有误问题。CPU、进程、线程的基础概念CPU:计算机的核心是CPU,它承担了所有的计算任务,同时CPU也是执行指令的芯片。一颗CPU核心在同一时间只能做一件事情(执行一条指令)。进程:进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。线程:在早期的操作系统中并没有线程的概念,进程是拥有资源和独立运行的最小单位,也是程序执行的最小单位。

2021-09-02 13:40:54 163

原创 面向猴子编程 错删表数据的修复方案

引文人生在世,难免有手滑的时候。没有悄悄咪咪删过表数据的程序员的人生,一定是不完美的。特别是连续加班后,带着昏沉沉的大脑,难免会一个不留神,写下了罪恶的foreach remove语句。满怀信心的一看数据库。啪,快乐没有了!表数据因为不合适的查询条件,进行了全表数据删除的操作!此时的你一定万分慌张,甚至已经收拾好行李,准备下一秒就提着桶跑路了!为什么要跑路呢?因为你不知道接下来该如何处理,只能依靠工具猴最原始的自我保护机制,驱使自己前进。除了跑路,我们还能做些什么呢?!别慌,下面就来讲讲遇到这种情况

2021-05-06 17:45:01 519 3

原创 面向猴子编程 全链路追踪技术

目录全链路跟踪opentracing介绍目前主流的两种链路框架zipkin,jaeger全链路跟踪为什么要使用全链路追踪如图所示,在一个微服务架构的请求周期内,一个请求可能会链式调用多个服务。而对于每个服务而言,每个服务可能由一台服务器或者是一个服务器集群构成。工作中我们可能会碰到以下问题需要知道单个请求的响应时间需要知道单个服务内每个IO耗时需要知道服务之间的调用关系需要知道一段时间内对于单个接口的请求数/异常数需要知道单个接口的健康程度需要知道当前处理请求的服务器的IP

2021-03-12 10:03:48 436

原创 微服务学习笔记 三大编程范式

三大编程范式包括,结构化编程,面向对象编程,函数式编程。结构化编程范式结构化编程是指将复杂程序递归拆分成一系列更小的,可证明的单元(函数),之后通过编写测试来试图证明这些函数是错误的。如果无法证伪这些函数,就可以认为这些函数足够正确,进而推导整个程序是正确的。(注意,这里是用科学论证法进行验证,只要函数无法证伪,就能认为其足够正确;而数学论证则要求证明函数的正确性)由于需要递归的将程序拆分成更小的,可证明的单元,而使用goto语句会导致某个模块无法递归拆分,进而违背了结构化编程范式。所以,在结构化编程

2021-03-03 23:13:16 216 2

原创 微服务学习笔记 演进式架构 适应度函数概念

适应度函数定义如下:架构的适应度函数为某些架构特征提供了客观的完整性评估。适应度函数,本质上就是一组评估函数,用以评估架构在不同维度上的表现(性能、可靠性、安全性、伸缩性、代码规范等),并从全局角度进行平衡,从而实现增量和引导式演进。适应度函数不单指特定的一种方法(如,单体测试),而是所有能够评估架构性能的方法。适应度函数可以是单体测试、功能性测试、监控工具等。但是不是所有方法都是适应度函数,只有该方法能够评估架构性能的时候,才是适应度函数(用于验证业务的单体测试就不是适应性函数)。架构师通过适应度

2021-02-25 15:57:58 1333 1

原创 微服务学习笔记 事件溯源

什么是事件溯源传统的数据对象持久化主要是将数据对象映射到数据库的表中。其中列代表了对象的属性,而行代表了一个对象(例如mysql中的行与列的关系)。传统的数据对象持久化只会保存当前对象状态,而不会保存变更之前的状态。事件溯源和传统的数据对象持久化不同的是,其主要操作对象是事件。聚合对象通过一系列事件存储在数据库中,每个事件代表聚合对象的状态改变,通过加载事件和重放事件来获取当前或者某个时间内的对象状态。事件溯源的具体操作在传统的数据持久化的操作中,直接对数据库的数据对象进行增删改查。在事件溯源

2021-02-18 15:49:39 305

原创 微服务学习笔记 K8S、ISTIO、微服务、容器不得不说的故事

微服务运行在容器内;容器依靠K8S进行编排、服务发现、负载均衡等;Istio和K8S进行融合,在利用K8S的一些功能的基础上(服务注册),对K8S进行功能的扩展,追加了一些服务治理功能(熔断、限流、动态路由、调用链追踪)。微服务与容器为了微服务的快速部署和迭代,如今的微服务架构中,通常将微服务部署在容器内。使用容器的好处K8SK8S是一个基于容器技术的分布式架构方案。利用K8S,我们可以很好的对容器进行管理。其架构如下:K8S的最基础单位是Pod,一个Pod下可以支持许多容器,Pod中的容器.

2021-02-01 17:35:47 5604 2

原创 微服务学习笔记 Saga模式

单体架构下,大多数采用的事务的ACID原则来保证事务,但是在微服务架构下,由于要保证低耦合等的要求,采用ACD Saga的模式来保证事务。(虽然也可以使用分布式事务,即"两阶段提交",但是这会导致服务和服务之间的强耦合)所谓的Saga,就是通过使用异步消息来协调一系列本地事务,从而维护多个服务之间的数据一致性。每个TXN是一个本地事务,当本地事务提交后,通过异步消息来告知下个服务开始执行其本地事务,以此类推。使用Saga是不考虑ACID的I(隔离性)的。此外,和使用分布式事务不同,每完成一个本地事务

2021-01-24 22:37:37 417 1

原创 微服务学习笔记 服务间消息传递架构(消息代理)

服务间消息传递架构通常分为两种,一种是无代理消息架构(服务和服务之间直接传递消息),一种是基于代理的消息架构(服务把消息传递给消息代理,消息代理将消息再传递给接收方)无代理消息架构的优劣优势有着更低的延迟,无须经过代理避免了因为消息代理而出现的问题复杂度低,无须维护消息代理劣势必须使用服务发现机制来找到接收方消息无法保存,发送方和接收方必须同时在线代理消息架构的优劣优势发送方不需要知道接收方的位置,也不必关心接收方是否在线,只要将消息交给消息代理即可能够缓存消息,可以保持

2021-01-24 17:04:36 672

原创 Go学习笔记 制作一个能被世界人民使用的工具包!

在github上创建一个公共库将公共库使用git关联到本地项目git initgit add .git commit -m '提交信息'// 将本地仓库与远程仓库绑定(地址为远程仓库的地址)git remote add origin https://github.com/mushi/test.gitgit push origin masterPS:在这过程中你可能会遇到"fatal: refusing to merge unrelated histories"的问题,你可以参.

2021-01-23 19:13:31 136

原创 微服务学习笔记 服务发现和注册

服务的发现和注册有两种模式应用层服务发现模式这种模式下,服务端直接自己向注册中心进行注册(自注册模式),而客户端也直接通过查询注册中心获取服务实例的地址来调用服务(客户端有时可能会缓存服务实例)。这种模式的好处在于,他可以处理多平台部署问题,即如果在K8S上部署了一些服务,另一些服务在其他的遗留环境下,那么使用这种模式就能发现所有不同环境下的服务。而基于K8S的服务发现仅能发现部署在K8S下的服务。弊端在于需要为每种语言提供服务发现库,而且开发者需要自己负责和管理服务注册表。平台层服务发现模式

2021-01-20 20:21:49 112

原创 微服务学习笔记 分层架构和六边形架构

分层架构传统的mvc三层架构,上层依赖于下层,层与层之间有严格的界限。但是一旦业务庞大起来后,为了业务需要,就会增加新的层。新层往往有边界模糊等问题。此外,因为上层依赖于下层,当数据来源出现变更的时候(mysql专为redis或者es),数据源的切换,也会变得极为麻烦。六边形架构六边形架构有别于传统的分层架构,将上层对下层的依赖进行了依赖倒置,高层模块不再依赖低层模块,两者都依赖其抽象。通过适配器,将输入和输出都放到了设计的边缘部分。整个架构不再关心公开的是REST或者是GRPC,也不再关心从何处获

2021-01-19 21:58:57 847 2

原创 微服务学习笔记 模式

模式是针对特定上下文中发生的问题的可重用解决方案。常用的模式结构包含:需求结果上下文相关模式需求:必须解决的问题需求部分描述了必须解决的问题和围绕这个问题的特定上下文环境。需求之间可能会有冲突,所以必须把需求按照优先级进行排序。结果上下文:采用模式后可能带来的后果包含三个部分好处:这个模式的好处以及他解决了什么需求弊端:这个模式的弊端和他没有解决那些需求问题:这个模式锁引入的新问题相关模式:模式之间存在5种不同类型的关系前导:是催生这个模式的需求的模式。如微服务架构模式是

2021-01-19 14:38:51 90

原创 微服务学习笔记 微服务的优劣

优势使大型的复杂应用程序可以持续交付和持续部署拥有持续交付和持续部署所需要的可测试性(因为服务小,自动化测试容易)拥有持续交付和持续部署所需要的可部署性(每个服务可以独立于其他服务进行部署)使开发团队能够自主且松散耦合(团队成员能够自由组合,负责部分业务)每个服务都相对较小且容易维护服务可以独立扩展每个服务都可以部署在适合他们需求的硬件上,选择最为合适的硬件。而单体架构选择的硬件必须满足所有的服务需求更好的容错性可以实现更好的故障隔离,某个服务中的内存泄漏不会影响到其他服务

2021-01-19 14:17:02 83

原创 微服务学习笔记 微服务和SOA的异同

智能管道类似A——ESB——B的架构应用A要访问服务B,A要先发数据给ESB,然后ESB调用B,B产生的数据返给ESB,然后ESB再返给A。ESB起到了类似于中间层的作用,对A的请求进行过滤和分发,之后再传递给相应的B获取响应;而B返回的响应先给ESB进行组合处理后再返回给A哑管道类似A——B的架构去掉了ESB中间层,微服务体系的管道只提供路由或者负载均衡之类的,不承载业务逻辑,或者是MQ之类的异步消息中间件,管道根本不关心具体传送的数据参考:参考文章...

2021-01-19 13:47:26 102

原创 PHP相关 mac安装grpc扩展

pecl install grpc// 使用brew安装php的php.ini路径/usr/local/etc/php/7.2// 在php.ini中追加extension=grpc.so// 重启phpbrew services restart php@7.2使用的时候要在composer里追加"require": { "grpc/grpc": "~1.30.0"}参考:grpcPHP官方...

2021-01-11 19:37:25 498

原创 GoMicro学习笔记 一台服务器上同时开启Server和WebClinet注意事项

本注意事项基于go-microV2可以同时在一台服务器上的不同端口启动gomicro的服务端和客户端,如果不指定rigistry的话,默认是使用mdns作为注册中心当在一个进程里面同时启动服务端和客户端的时候(同步启动或者使用goroutine异步启动)一旦有一个newService中进行了registry配置,则启动的service都会使用这个注册中心 // 这是server的配置 svc1 := micro.NewService( micro.Name("server"), micr

2021-01-10 17:51:04 165

原创 Go学习笔记 Docker安装Nacos教程

第一步:下载镜像docker pull nacos/nacos-server:1.3.1第二步:创建挂载文件目录mkdir -p /opt/nacos/init.dcd /opt/nacos/init.dtouch custom.properties第三步:添加配置在custom.properties文件中填写如下配置:management.endpoints.web.exposure.include=*第四步:创建并启动容器docker run -d -p 8848:8848 -

2021-01-10 17:34:06 138

原创 GoMicro学习笔记 简易搭建go micro服务并使用http形式请求这个服务

启动go micro服务创建好项目后,使用go mod init <项目名>生成一个go.mod文件获取micro工具包go get github.com/micro/micro获取protoc-gen-go(通过此可以直接生成go语言对应的编译代码)go get github.com/micro/protobuf/{proto,protoc-gen-go}启动Consul(使用consul作为注册中心注册所有服务)docker run consul编写greeter.pr

2020-12-30 17:17:10 597

原创 GoMicro学习笔记 Micro和GoMicro

Micro是运行时工具集,而GoMicro则是后端服务框架。Micro如下图所示,micro类似于中间层的作用,手机,web等通过micro中相应的API,BOT,WEB等工具,调用gomicro框架中的服务Micro Api主要功能在于将http请求转向到内部服务。即通过Micro Api将内部服务暴露给外部http请求。 Micro Proxy可以让服务客户端直接调用服务。与Mirco API不同的是,api主要是将rpc转成http形式给外部,而proxy则是只能使用rpc形式Go.

2020-12-27 21:34:37 286

原创 TCP/IP随笔 http和tcp的区别

简单来说,通常情况下http是基于tcp的。tpc是传输层的,而http是应用层的。tcp的优势在于长连接,即三次握手之后,理想情况下,除非一方主动关闭连接(四次挥手),tcp连接将一直持续下去(其中可能会受到防火墙等因素的干扰而关闭)。http是短连接,在已建立tcp连接的基础上,使用“请求—响应”的方式进行数据交换。http需要客户端向服务器发出请求后,服务器端才能回复数据。此外,应用层使用套接字(socket)将数据传递给传输层,并进一步使用传输层进行数据通信。参考:HTTP与TCP的区.

2020-12-27 16:30:49 123

原创 Go学习笔记 Context上下文

什么是上下文Context 也叫作“上下文”,是一个比较抽象的概念,一般理解为程序单元的一个运行状态、现场、快照。其中上下是指存在上下层的传递,上会把内容传递给下,程序单元则指的是 Goroutine。每个 Goroutine 在执行之前,都要先知道程序当前的执行状态,通常将这些执行状态封装在一个 Context 变量中,传递给要执行的 Goroutine 中。(个人理解为goroutine运行时的环境)Context的结构type Context interface { // 返回该上下

2020-12-25 18:10:40 276

原创 Go学习笔记 值拷贝和引用拷贝

只有map,slice,chan是引用类型,其拷贝为引用拷贝值拷贝package main import "fmt" func modify(a [3]int) { a[0] = 4 } func main() { a := [3]int{1, 2, 3} modify(a) fmt.Println(a) }这种情况是值拷贝,返回[1, 2, 3]引用拷贝func main() { a := make([]i

2020-12-23 15:34:58 690

原创 RocketMQ学习笔记 发送消息和消费消息

RocketMQ发送的消息分为普通消息,顺序消息,事务消息,延时消息四种普通消息的发送方式又分为同步(Sync)发送、异步(Async)发送和单向(Oneway)发送其中同步发送如图异步发送单向发送因为rocketmq的异步是开了一个线程去做的,而php是单线程的,所以目前的php rocketmq的示例sdk是同步发送的普通消息的情况下,不能保证消息的消费先后顺序。集群消费会将消息平均分配给同集群下的所有消费者。如果消费者没有消费消息,会导致消息一直处于未消..

2020-12-13 20:14:45 466

原创 RocketMQ学习笔记 名词解释

rocketMQ中,主要使用topic和tag对消息进行分类。其中,topic是一级分类,而tag是进一步的二级分类。每个Topic下会由一到多个队列来存储消息一个group下能有多个consumer。每个consumer生产或消费同一类消息,且消息发布或订阅的逻辑一致集群消费一个Group ID所标识的所有Consumer平均分摊消费消息。例如某个Topic有9条消息,一个Group ID有3个Consumer实例,那么在集群消费模式下每个实例平均分摊,只消费其中的3条消息。广播消费一个Gr.

2020-12-13 17:54:56 307

原创 Go语言学习笔记 利用cron执行定时脚本

import "github.com/robfig/cron"func main() { // 启动一个gorutine执行定时脚本 go func() { // 定时脚本 global.AppLog.Info("Starting FillBillCycle...") c := cron.New() // 新建一个定时任务对象 c.AddFunc("20 */2 * * * *", func() { Cycle() }) // 给对象增加定时任务 c.St.

2020-12-12 19:02:24 300

原创 Go语言学习笔记 grom追加事务

// 开始事务tx := db.Begin()// 在事务中做一些数据库操作(从这一点使用'tx',而不是'db')tx.Create(...)// ...// 发生错误时回滚事务tx.Rollback()// 或提交事务tx.Commit()基于grom,go中如何接收错误并回滚func test() (finErr error) { // 开启事务 tx := db.Begin() global.AppLog.Info("Begin Transaction...")

2020-12-12 18:43:20 263

原创 Go语言学习笔记 gRPC基础学习

1.利用protobuf定义一个服务,类似于定义一个接口syntax = "proto3";option java_package = "io.grpc.examples";package helloworld;// The greeter service definition.service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {}}// The requ

2020-11-19 13:50:07 148

原创 Go语言学习笔记 时间转换函数

// TimeToTimestamp string类型的时间转为时间戳func TimeToTimestamp(t string) int64 { if t == "" { return 0 } timeLayout := "2006-01-02" switch len(t) { case 10: timeLayout = "2006-01-02" case 19: timeLayout = "2006-01-02 15:04:05" } loc, _ := time.Loa

2020-11-17 18:05:12 169

原创 ES学习笔记 常用搜索和更新

数据查找// 查找所有数据GET 索引/类型/_search{ "query": { "match_all": {} }}// 查找数据字段GET /ecommerce/product/_search{ "query": { "match_all": {} }, "_source": ["name", "price"]}// 查找具体某一条数据GET 索引/_search{ "query": { "bool": { "must": [

2020-10-22 14:46:42 207

原创 Mac PHP-FPM配置文件路径

/private/etc/php-fpm.d

2020-10-14 16:49:35 838

原创 数据库随笔 redis加锁方式

$redis->set($key, $value, array('nx', 'ex' => $ttl));nx代表key不存在的时候才可以设置值,否则设值失败ex代表过期时间,单位为秒px也是过期时间,单位为毫秒此方法通常用于给redis某个key进行加锁例如:keyA需要加锁,则:$redis->set(keyA_lock, 1, array('nx', 'ex' => 1));判断keyA_lock是否存在如果存在,则keyA已被上锁解锁的时候,删除相关锁

2020-09-29 14:28:00 372

原创 ES学习笔记 ElasticSearch 聚合的简单使用

ES的聚合有两个概念,桶和指标其中,桶简单来说就是满足特定条件的文档的集合,类似于mysql中的group by而指标就是简单的数学运算(例如最小值、平均值、最大值,还有汇总),这些是通过文档的值来计算的。类似于mysql中的sum,count等聚合 是由桶和指标组成的。聚合语句的格式为可以参考官网curl -X GET "localhost:9200/cars/transactions/_search?pretty" -H 'Content-Type: application/json' -d

2020-09-25 11:05:27 221

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除