다음 칼럼에서는 golang tutorial에서 bash 명령 분석을 실행하기 위한 bash 함수를 캡슐화한 golang에 대해 소개하겠습니다. 도움이 필요한 친구들에게 도움이 되길 바랍니다!
Hystrix
Hystrix
는 Netflex
에서 개발되었으며 오픈 소스입니다. 기본적인 회로 차단기 기능을 제공하는 구성 요소입니다. Hystrix
는 Command
에 다운그레이드 전략을 캡슐화하고 run
및 fallback
이라는 두 가지 방법을 제공합니다. 전자는 일반 논리를 나타냅니다. 마이크로서비스 간 호출 등... 실패가 발생하면 fallback
메서드가 실행되어 결과를 반환하는 것을 보장된 작업으로 이해할 수 있습니다. 짧은 시간 내에 정상적인 로직이 자주 실패하는 경우 단락이 발생할 수 있습니다. 즉, 후속 요청은 더 이상 run
을 실행하지 않고 fallback
을 직접 실행합니다. Hystrix
에 대한 자세한 내용은 https://github.com/NETFLIX/Hystrix
에서 확인할 수 있으며, hystrix-go
를 사용합니다. code>go hystrix
구현, 더 정확하게는 단순화된 버전입니다. 단지 마지막 업데이트인가요, 아니면 2018년에 졸업했다는 pr
인가요?
왜 이러한 도구가 필요한가요?
hystrix-go
实现了,因此有了这篇文章。
Hystrix
Hystrix
是由 Netflex
开发的一款开源组件,提供了基础的熔断功能。 Hystrix
将降级的策略封装在 Command
中,提供了 run
和 fallback
两个方法,前者表示正常的逻辑,比如微服务之间的调用……,如果发生了故障,再执行 fallback
方法返回结果,我们可以把它理解成保底操作。如果正常逻辑在短时间内频繁发生故障,那么可能会触发短路,也就是之后的请求不再执行 run
,而是直接执行 fallback
。更多关于 Hystrix
的信息可以查看 https://github.com/Netflix/Hystrix
,而hystrix-go
则是用 go
实现的 hystrix
版,更确切的说,是简化版。只是上一次更新还是 2018年 的一次 pr
,也就毕业了?
为什么需要这些工具?
比如一个微服务化的产品线上,每一个服务都专注于自己的业务,并对外提供相应的服务接口,或者依赖于外部服务的某个逻辑接口,就像下面这样。
假设我们当前是 服务A
,有部分逻辑依赖于 服务C
,服务C
又依赖于 服务E
,当前微服务之间进行 rpc
或者 http
通信,假设此时 服务C
调用 服务E 失败,比如由于网络波动导致超时或者服务E由于过载,系统E 已经down掉了。
调用失败,一般会有失败重试等机制。但是再想想,假设服务E已然不可用的情况下,此时新的调用不断产生,同时伴随着调用等待和失败重试,会导致 服务C对服务E的调用而产生大量的积压,慢慢会耗尽服务C的资源,进而导致服务C也down掉,这样恶性循环下,会影响到整个微服务体系,产生雪崩效应。
虽然导致雪崩的发生不仅仅这一种,但是我们需要采取一定的措施,来保证不让这个噩梦发生。而 hystrix-go
就很好的提供了 熔断和降级的措施。它的主要思想在于,设置一些阀值,比如最大并发数(当并发数大于设置的并发数,拦截),错误率百分比(请求数量大于等于设置 的阀值,并且错误率达到设置的百分比时,触发熔断)以及熔断尝试恢复时间等 。
使用
hystrix-go
的使用非常简单,你可以调用它的 Go
或者 Do
方法,只是 Go
方法是异步的方式。而 Do
方法是同步方式。我们从一个简单的例子开启。
_ = hystrix.Do("wuqq", func() error { // talk to other services _, err := http.Get("https://www.baidu.com/") if err != nil { fmt.Println("get error:%v",err) return err } return nil }, func(err error) error { fmt.Printf("handle error:%v\n", err) return nil })
Do
函数需要三个参数,第一个参数 commmand
名称,你可以把每个名称当成一个独立当服务,第二个参数是处理正常的逻辑,比如 http
调用服务,返回参数是 err
서비스 A, 일부 로직은 <code>서비스 C
에 종속되고, 서비스 C
는 서비스 E
에 종속되며, 현재 마이크로서비스는 rpc입니다.
또는 http
통신, 네트워크 변동으로 인한 시간 초과 또는 과부하로 인한 서비스 E 등 현재 서비스 C
가 서비스 E 호출에 실패했다고 가정하면, 시스템 E가 다운되었습니다. 호출이 실패하면 일반적으로 재시도 실패 등 메커니즘. 하지만 다시 생각해 보세요. 서비스 E를 이미 사용할 수 없다고 가정하면 이때 새로운 통화가 계속 생성되고 통화 대기 및 재시도 실패가 동반되어 서비스 C에서 서비스 E로의 통화 백로그가 크게 발생하게 됩니다. 천천히, 서비스 C의 리소스가 고갈되어 서비스 C가 중단될 수도 있습니다. 이 악순환은 전체 마이크로서비스 시스템에 영향을 미치고 눈사태 효과를 낳습니다.

hystrix-go
는 매우 우수한 회로 차단기 및 다운그레이드 조치를 제공합니다. 주요 아이디어는 최대 동시성 수(동시성 수가 설정된 동시성 수보다 클 때 차단), 오류율 백분율(요청 수가 다음보다 크거나 같을 때)과 같은 일부 임계값을 설정하는 것입니다. 설정된 임계값 및 오류율이 설정된 백분율에 도달함, 퓨즈 트리거) 및 퓨즈 시도 복구 시간 등 🎜사용법
🎜hystrix-go
는 사용이 매우 간단하며 Go
또는 Do
메서드이지만 Go
메서드는 비동기식입니다. Do
메서드는 동기식입니다. 간단한 예부터 시작해 보겠습니다. 🎜hystrix.ConfigureCommand("wuqq", hystrix.CommandConfig{ Timeout: int(3 * time.Second), MaxConcurrentRequests: 10, SleepWindow: 5000, RequestVolumeThreshold: 10, ErrorPercentThreshold: 30, }) _ = hystrix.Do("wuqq", func() error { // talk to other services _, err := http.Get("https://www.baidu.com/") if err != nil { fmt.Println("get error:%v",err) return err } return nil }, func(err error) error { fmt.Printf("handle error:%v\n", err) return nil })🎜
Do
함수에는 세 개의 매개변수가 필요합니다. 첫 번째 매개변수는 commmand
이름입니다. 두 번째 매개변수는 정상적으로 처리됩니다. , 예를 들어 http
호출 서비스의 경우 반환 매개변수는 err
입니다. 처리 | 호출이 실패하면 세 번째 매개변수 논리가 실행되며 이를 보장된 작업이라고 합니다. 서비스 오류율이 너무 높고 퓨즈가 열리기 때문에 후속 요청도 이 기능을 직접 콜백합니다. 🎜🎜구성된 규칙에 따라 퓨즈가 켜지거나 꺼지기 때문에 당연히 원하는 값을 설정할 수 있습니다. 🎜package mainimport ( "fmt" "github.com/afex/hystrix-go/hystrix" "net/http" "time")type Handle struct{}func (h *Handle) ServeHTTP(r http.ResponseWriter, request *http.Request) { h.Common(r, request)}func (h *Handle) Common(r http.ResponseWriter, request *http.Request) { hystrix.ConfigureCommand("mycommand", hystrix.CommandConfig{ Timeout: int(3 * time.Second), MaxConcurrentRequests: 10, SleepWindow: 5000, RequestVolumeThreshold: 20, ErrorPercentThreshold: 30, }) msg := "success" _ = hystrix.Do("mycommand", func() error { _, err := http.Get("https://www.baidu.com") if err != nil { fmt.Printf("请求失败:%v", err) return err } return nil }, func(err error) error { fmt.Printf("handle error:%v\n", err) msg = "error" return nil }) r.Write([]byte(msg))}func main() { http.ListenAndServe(":8090", &Handle{})}🎜 위에서 구성한 값의 의미를 설명하세요.🎜
- Timeout: 执行
command
的超时时间。 - MaxConcurrentRequests:
command
的最大并发量 。 - SleepWindow:当熔断器被打开后,
SleepWindow
的时间就是控制过多久后去尝试服务是否可用了。 - RequestVolumeThreshold: 一个统计窗口10秒内请求数量。达到这个请求数量后才去判断是否要开启熔断
- ErrorPercentThreshold:错误百分比,请求数量大于等于
RequestVolumeThreshold
并且错误率到达这个百分比后就会启动熔断
当然你不设置的话,那么自动走的默认值。
我们再来看一个简单的例子:
package mainimport ( "fmt" "github.com/afex/hystrix-go/hystrix" "net/http" "time")type Handle struct{}func (h *Handle) ServeHTTP(r http.ResponseWriter, request *http.Request) { h.Common(r, request)}func (h *Handle) Common(r http.ResponseWriter, request *http.Request) { hystrix.ConfigureCommand("mycommand", hystrix.CommandConfig{ Timeout: int(3 * time.Second), MaxConcurrentRequests: 10, SleepWindow: 5000, RequestVolumeThreshold: 20, ErrorPercentThreshold: 30, }) msg := "success" _ = hystrix.Do("mycommand", func() error { _, err := http.Get("https://www.baidu.com") if err != nil { fmt.Printf("请求失败:%v", err) return err } return nil }, func(err error) error { fmt.Printf("handle error:%v\n", err) msg = "error" return nil }) r.Write([]byte(msg))}func main() { http.ListenAndServe(":8090", &Handle{})}
我们开启了一个 http
服务,监听端口号 8090
,所有请求的处理逻辑都在 Common
方法中,在这个方法中,我们主要是发起一次 http
请求,请求成功响应success
,如果失败,响应失败原因。
我们再写另一个简单程序,并发 11
次的请求 8090
端口。
package mainimport ( "fmt" "io/ioutil" "net/http" "sync" "time")var client *http.Clientfunc init() { tr := &http.Transport{ MaxIdleConns: 100, IdleConnTimeout: 1 * time.Second, } client = &http.Client{Transport: tr}}type info struct { Data interface{} `json:"data"`}func main() { var wg sync.WaitGroup for i := 0; i <p>由于我们配置 <code>MaxConcurrentRequests</code> 为10,那么意味着还有个 g 请求会失败:<br><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/020/a47bae3dcfa1730bb3b1136eddb4f59b-5.png?x-oss-process=image/resize,p_40" class="lazy" alt=""><br>和我们想的一样。</p><p>接着我们把网络断开,并发请求改成10次。再次运行程序并发请求 <code>8090</code> 端口,此时由于网络已关闭,导致请求百度失败:<br><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/020/a47bae3dcfa1730bb3b1136eddb4f59b-6.png?x-oss-process=image/resize,p_40" class="lazy" alt=""><br>接着继续请求:<br><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/020/a47bae3dcfa1730bb3b1136eddb4f59b-7.png?x-oss-process=image/resize,p_40" class="lazy" alt=""><br>熔断器已开启,上面我们配置的<code>RequestVolumeThreshold</code> 和 <code>ErrorPercentThreshold</code> 生效。</p><p>然后我们把网连上,五秒后 (<code>SleepWindow</code>的值)继续并发调用,当前熔断器处于半开的状态,此时请求允许调用依赖,如果成功则关闭,失败则继续开启熔断器。<br><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/020/a47bae3dcfa1730bb3b1136eddb4f59b-8.png?x-oss-process=image/resize,p_40" class="lazy" alt=""><br>可以看到,有一个成功了,那么此时熔断器已关闭,接下来继续运行函数并发调用:<br><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/020/24be5795ca6d697af3d1d7ffdfdafc03-9.png?x-oss-process=image/resize,p_40" class="lazy" alt=""><br>可以看到,10个都已经是正常成功的状态了。</p><p>那么问题来了,为什么最上面的图只有一个是成功的?5秒已经过了,并且当前网络正常,应该是10个请求都成功,但是我们看到的只有一个是成功状态。通过源码我们可以找到答案:<br>具体逻辑在判断当前请求是否可以调用依赖</p><pre class="brush:php;toolbar:false">if !cmd.circuit.AllowRequest() { ...... return }
func (circuit *CircuitBreaker) AllowRequest() bool { return !circuit.IsOpen() || circuit.allowSingleTest()}func (circuit *CircuitBreaker) allowSingleTest() bool { circuit.mutex.RLock() defer circuit.mutex.RUnlock() now := time.Now().UnixNano() openedOrLastTestedTime := atomic.LoadInt64(&circuit.openedOrLastTestedTime) if circuit.open && now > openedOrLastTestedTime+getSettings(circuit.Name).SleepWindow.Nanoseconds() { / swapped := atomic.CompareAndSwapInt64(&circuit.openedOrLastTestedTime, openedOrLastTestedTime, now) //这一句才是关键 if swapped { log.Printf("hystrix-go: allowing single test to possibly close circuit %v", circuit.Name) } return swapped } return false}
这段代码首先判断了熔断器是否开启,并且当前时间大于 上一次开启熔断器的时间+ SleepWindow
的时间,如果条件都符合的话,更新此熔断器最新的 openedOrLastTestedTime
,是通过 CompareAndSwapInt64
原子操作完成的,意外着必然只会有一个成功。
此时熔断器还是半开的状态,接着如果能拿到令牌,执行run
函数(也就是Do传入的第二个简单封装后的函数),发起 http
请求,如果成功,上报成功状态,关闭熔断器。如果失败,那么熔断器依旧开启。
以上就是大体的流程讲解,下一篇文章将解读核心源码以及进一步当思考。
更多相关技术文章,请访问go语言教程栏目!
위 내용은 hystrix-go 사용법과 원리에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

C는 하드웨어 리소스 및 고성능 최적화가 직접 제어되는 시나리오에 더 적합하지만 Golang은 빠른 개발 및 높은 동시성 처리가 필요한 시나리오에 더 적합합니다. 1.C의 장점은 게임 개발과 같은 고성능 요구에 적합한 하드웨어 특성 및 높은 최적화 기능에 가깝습니다. 2. Golang의 장점은 간결한 구문 및 자연 동시성 지원에 있으며, 이는 동시성 서비스 개발에 적합합니다.

Golang은 실제 응용 분야에서 탁월하며 단순성, 효율성 및 동시성으로 유명합니다. 1) 동시 프로그래밍은 Goroutines 및 채널을 통해 구현됩니다. 2) Flexible Code는 인터페이스 및 다형성을 사용하여 작성됩니다. 3) NET/HTTP 패키지로 네트워크 프로그래밍 단순화, 4) 효율적인 동시 크롤러 구축, 5) 도구 및 모범 사례를 통해 디버깅 및 최적화.

GO의 핵심 기능에는 쓰레기 수집, 정적 연결 및 동시성 지원이 포함됩니다. 1. Go Language의 동시성 모델은 고루틴 및 채널을 통한 효율적인 동시 프로그래밍을 실현합니다. 2. 인터페이스 및 다형성은 인터페이스 방법을 통해 구현되므로 서로 다른 유형을 통일 된 방식으로 처리 할 수 있습니다. 3. 기본 사용법은 기능 정의 및 호출의 효율성을 보여줍니다. 4. 고급 사용에서 슬라이스는 동적 크기 조정의 강력한 기능을 제공합니다. 5. 레이스 조건과 같은 일반적인 오류는 Getest-race를 통해 감지 및 해결할 수 있습니다. 6. 성능 최적화는 sync.pool을 통해 개체를 재사용하여 쓰레기 수집 압력을 줄입니다.

Go Language는 효율적이고 확장 가능한 시스템을 구축하는 데 잘 작동합니다. 장점은 다음과 같습니다. 1. 고성능 : 기계 코드로 컴파일, 빠른 달리기 속도; 2. 동시 프로그래밍 : 고어 라틴 및 채널을 통한 멀티 태스킹 단순화; 3. 단순성 : 간결한 구문, 학습 및 유지 보수 비용 절감; 4. 크로스 플랫폼 : 크로스 플랫폼 컴파일, 쉬운 배포를 지원합니다.

SQL 쿼리 결과의 정렬에 대해 혼란스러워합니다. SQL을 학습하는 과정에서 종종 혼란스러운 문제가 발생합니다. 최근 저자는 "Mick-SQL 기본 사항"을 읽고 있습니다.

기술 스택 컨버전스와 기술 선택의 관계, 소프트웨어 개발에서 기술 스택의 선택 및 관리는 매우 중요한 문제입니다. 최근에 일부 독자들은 ...

골란 ...

GO 언어로 세 가지 구조를 비교하고 처리하는 방법. GO 프로그래밍에서는 때때로 두 구조의 차이점을 비교하고 이러한 차이점을 ...에 적용해야합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

에디트플러스 중국어 크랙 버전
작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

Dreamweaver Mac版
시각적 웹 개발 도구
