다음 칼럼에서는 Golang이 높은 동시성 스파이크를 만났을 때 golang 튜토리얼 칼럼을 소개하겠습니다. 도움이 필요한 친구들에게 도움이 되길 바랍니다!
이따금씩 GO언어를 접할 수 있는 기회이기도 합니다. 저는 직장에서 건축 관련 일을 하고 있기 때문에 새로운 언어와 대중적인 언어에 주의를 기울여야 합니다. 이렇게 해서 저는 GO 언어의 세계에 들어갔습니다. GO는 나에게 완전히 새로운 경험을 선사했습니다.
한 가지 일을 하던 사람들은 종종 한 가지 일에 갇히게 됩니다. , 특히 구조를 클래스로 취급하는 것과 구조의 상속을 다루는 것, 쓰기 측면은 너무 많이 생각하면 다루기가 정말 어렵습니다. 하지만 쓰다 보면 점차 익숙해지고, 눈도 점점 즐거워지네요.
GO에 익숙해진 후 잠시 멈추고 GO의 단순성에 대해 계속 생각했습니다. (코드 스타일이 일관되고 사용하기 간결하고 엉성하지 않으며 배포가 매우 간단하고 컴파일 속도가 빠릅니다. 빠르다고 설명할 수 있습니다. 프로젝트 시스템과 아키텍처는 어떤 변화를 가져올까요? 하지만 그 당시에는 이것이 얼마나 도움이 될지 전혀 예상하지 못했습니다. 나중에 시스템이 점차 GO로 구현되기 시작했습니다. 더 많이 사용하면서 천천히 깨달았습니다.
이봐~, 더 이상 시스템을 구축할 필요가 없습니다. 배포를 위한 종속 환경(환경을 배포하지 않고 게시하다보니 처음에는 정말 익숙하지 않았고 항상 뭔가 빠진 듯한 느낌이 들었습니다.
다른 사람들이 작성한 코드를 볼 때 아무런 거부감이 없었습니다. 코드는 제가 직접 작성한 것이 아니고, 자세히 읽어보니 제가 직접 작성한 것 같았습니다. JAVA와 PHP를 작성할 때 진심으로 코드를 읽는 것을 거부합니다.
개발이 간편해졌습니다. 특정 마이크로서비스 인터페이스를 작성하고, 인터페이스를 작성하고, 제출하면 몇 초 안에 온라인 상태가 됩니다~;
위에서는 주로 GO와의 만남과 GO가 나에게 미친 초기 영향에 대해 이야기했습니다. 어느 날 밤, GO 언어의 단순함이 많은 개선을 가져왔고, 내가 작업 중인 아키텍처 시스템이 갑자기 떠올랐습니다. GO를 사용하여 시스템 복잡성을 단순화하고 줄일 수 있습니까? 이 아이디어가 떠오른 이후로 계속 머릿속에 남아 있었습니다. 처음 아키텍처 작업을 시작했을 때를 돌이켜보면 미들웨어의 원리와 어떤 최적화가 성능을 향상시킬 수 있는지 보고 매우 기뻤습니다. 나는 그것을 마스터했다고 느낄 때까지 열심히 공부했고(물론 지금도 배우고 싶습니다), 시스템에서는 미들웨어 구성 요소가 많을수록 시스템이 더 강력해진다고 생각합니다. 하지만 오랫동안 하다 보면 시스템은 사용하기만 하면 되고, 아키텍처를 위해 구축할 수는 없다는 사실을 알게 될 것입니다. 전통적인 기술 스택에서 빼내려면 깊은 지식이 필요합니다. 기술 원리를 완전히 이해해야만 대체할 수 있고, 그래야만 문제를 일으키지 않고 감히 생각하고 실행할 수 있기 때문입니다. "모든 대륙은 로마로 통한다"라는 말이 있듯이, 건축 디자인의 목표는 최소한의 비용으로 많은 것을 성취하는 것입니다. 경우에 따라 여러 번 또는 수십 번의 요청을 지원할 수 있으며, 동일한 요청 볼륨에 도달하면 구현 및 배포가 매우 간단하고 작동 가능합니다. GO의 생각은 이 기간 동안 나에게 미묘하게 영향을 미쳤습니다.
저희 회사는 마이크로서비스를 하기로 결정하기 전까지 처음에는 Java를 사용하여 마이크로서비스를 했습니다. 나중에 다른 언어도 마이크로서비스를 할 수 있을까 고민하다가 자연스럽게 GO를 생각하게 됐고, 그래도 괜찮다는 생각이 들어서 계속해서 GO를 이용해 마이크로서비스를 작성하기 시작했습니다. 쓰기, Golang은 마이크로서비스 작성에 매우 적합하다는 것을 알았습니다. 편리하고 효율적이며 Tomcat을 캡슐화할 필요가 없습니다(이것을 jar 패키지에 넣는 것은 매우 부적절하다고 느낍니다). 시스템 의존성 없이(믿을 수 없다면 시도해 보세요.) GO를 좋아할수록 GO를 사용하여 후속 시스템을 재구성하고 싶습니다(글을 많이 씁니다). Java의 이러한 편리함을 접했을 때 마치 봄을 발견한 것 같습니다.) GO는 시스템 아키텍처의 관점에 깊은 영향을 미쳤습니다.
그런데 건축이란 정확히 무엇이며, 건축가는 어떻게 만들어지나요? 건축가가 되기 위한 8단계 고난은 다음과 같습니다.
첫 번째 문단: 벽돌을 옮기는 사람은 벽돌을 잘 하는 사람과 할 줄만 아는 사람으로 나뉩니다. 벽돌 옮기기(벽돌 옮기기에 남는 사람이 있고 나머지는 계속 발전하는 사람이 있다);
두 번째 문단: 벽돌을 옮길 수 있는 사람은 원리를 이해하는 사람과 움직이도록 프로그래밍하는 사람으로 나눌 수 있다 bricks;
세 번째 문단: 원리를 이해하는 사람 또한 끊임없이 연구하는 사람과 지식이 적은 사람으로 나누어집니다.
네 번째 문단: 지속적인 연구도 두 가지 유형으로 나눌 수 있습니다. 심층적이지만 광범위하지 않은 사람
다섯 번째 단락: 깊고 넓은 사람도 순수 기술 유형과 비즈니스 유형으로 구분됩니다(구분되기 시작함). 단락: 비즈니스 유형에는 시스템 및 요구 사항에 대한 우수한 의사소통과 특정 디자인 제어 능력이 필요합니다.
일곱 번째 단락: "아키텍처" 시스템에서 작업하는 이 레이어(Junior Architect)를 구축하려면 힙 미들웨어만 사용하는 것이 쉽습니다.
여덟 번째 문단: 이것은 매우 중요한 점입니다. 문제를 신중하게, 종합적으로 고려하고 의사소통을 잘 하세요. 기본 구현을 수행하고 기본 원칙을 이해하며 비즈니스, R&D, 테스트, 배포, 유지 관리 및 업그레이드의 다양한 관점에서 시작합니다. 현지 조건에 따라 구축된 "아키텍처"는 개발 효율성, 운영 효율성, 개발 품질, 비즈니스 유연성을 위한 것입니다. 유지보수의 편의를 위해 그런 사람들을 건축가라고 부를 수 있다.
플래시 세일 시스템을 구축할 때 처음에 떠오르고 가장 생각하기 쉬운 전통적인 기술 스택은 분산 세션, Redis 클러스터, 분산 캐시, nginx 역방향 프록시, nginx 딥 최적화, 머신 최적화 및 메시지 큐입니다. . 네, 캡 씨도 그 당시에 이것을 생각했고 이러한 "성숙한" 기술이 우리의 플래시 세일 시스템에 적용되는 것이 문제가 되지 않을 것이라고 믿었습니다. 또한 회사 내부 논의에서는 문제가 없을 것이라고 느꼈습니다. 이것. 그리고 우리는 다음과 같은 심층적인 연구를 수행했습니다:
1. 분산 세션 우리는 세션 검증의 목적을 달성하기 위해 세션을 저장하기 위해 Nginx+web+redis 클러스터를 사용하는 데 많은 노력을 기울였습니다. -point 세션은 다음과 같습니다. 그림과 같습니다:
언뜻 보면 문제가 없습니다. 트래픽이 정말 많을 때 Nginx와 웹 서버를 추가하는 것도 가능합니다. 수평적 확장을 충족하지만 트래픽이 수억에 도달한 후에는 비용이 약간 높으며 왕복 네트워크 요청 세션의 시간을 짜내고 싶습니다(그때 항상 뭔가를 느꼈습니다). 잘못되었습니다), nginx도 트래픽이 많은 경우 때때로 504를 표시합니다.
2. 분산 캐시는 매우 간단해 보이지만 대용량 및 동시성 시스템에서는 매우 복잡한 문제입니다.
1) 캐시 일관성(이것을 사용하는 경우) , 잘 처리하지 않으면 과매도 발생);
2) 캐시 침투;
3) 캐시 눈사태;
4) 캐시 블랙홀 문제:
5) 개 더미 효과;
...주의해야 할 사항이 많습니다. 간단히 말해서 분산 캐시는 매우 다양하고 가치가 있지만, 높은 동시성과 대규모 트래픽을 충족할 수 있는 분산 캐시 시스템을 구축하려면 강력한 기술팀의 지원이 필요합니다. 구현도 매우 복잡하므로 여기서는 자세히 설명하지 않겠습니다.
그러나 문제가 없어 보이는 솔루션에는 구현하기가 "너무 어렵고" 한계가 매우 높습니다. 리소스 비용도 상당히 높습니다. 세션은 수평 확장을 충족해야 하며, Redis 클러스터를 포함하여 웹 캐시도 수평 확장을 충족해야 합니다. 유일한 방법은 클러스터를 지속적으로 추가하는 것입니다.
간단한 예를 들어보겠습니다. 아키텍처의 중요성을 설명하기 위해) 현재 단일 머신이 있고 인터페이스의 처리 용량이 5000QPS(8코어 및 8G)이며 플래시 판매를 위해 수억 개의 트래픽을 즉시 처리해야 한다고 가정합니다. 플래시 세일 시작 시 트래픽은 300W로 추산되며 평균 대기 시간은 7초로 계산됩니다(인터페이스는 3.5WQPS 허용). 결과적으로 우리 시스템에는 거의 90개의 인터페이스가 필요합니다. 여기에는 다른 지원 서버가 포함되지 않습니다. 동일한 요구 사항을 가진 이러한 지원 서버는 다음과 같이 간략하게 설명됩니다.
1 . 우선 nginx 수준은 동일한 수준의 처리 기능을 가져야 합니다(각 단위는 최적화 없이 약 2WQPS, 약 20개 단위로 추정됩니다).
2. 웹 인터페이스도 해당 수준으로 확장해야 합니다(90개 예상).
3. Reids 여러 제품을 클러스터링하는 것이 경우에 따라 유용합니다(단일 제품의 경우 개수가 많으면 클러스터링이 쓸모가 없습니다).
위는 분산 세션이 충족해야 하는 시스템 요구 사항이며 분산 캐시는 포함되지 않습니다. 배포는 고려되지 않았습니다. 구현하기가 정말 복잡하고, 4~5년의 경험을 가진 한두 사람이 정말 짧은 시간에 완료할 수 없습니다. 이를 단순화하는 다른 방법을 생각해 볼 수 있습니까? 대답은 '예'입니다. 첫째, 원리를 이해해야 하고, 둘째, 아키텍처에서 뺄셈을 해야 합니다. 사용하지 않으면 최적화할 필요가 없습니다.
어디에서 최적화해야 할까요?
1) 권한 확인 원칙에 따라 플래시 킬 동시성에서 세션을 생략할 수 있습니다.
2) 분산 캐시를 사용할 수 없습니다(대신 인터페이스 사용). 3) nginx를 넣습니다. 도 생략(운영 및 유지 관리의 어려움 감소)
4) redis 클러스터도 생략할 수 있습니다.
그래서 하나와 둘이 제거되는데 어떻게 플래시 세일을 할 수 없는 걸까요? 하지만 이제 GO 언어 기능을 결합하여 새로운 아이디어를 제공할 수 있습니다.
1. Nginx를 생략하고 GO를 직접 사용하여 포트 노출 서비스를 시작할 수 있습니다.
2. 분산 세션 솔루션, 서버 측 코드 수준 확인 대신 쿠키 방법 또는 wt 방법을 사용합니다.
3. Oversell은 Redis 클러스터 대신 인터페이스 형식을 사용합니다.
4. 로드 밸런싱은 저렴한 SLB를 사용합니다. );
플래시 세일 최적화 후 프레지던트 아키텍처는 아래 그림의 구조로 표시될 수 있습니다. 자세한 방법은 "Go High Concurrency Flash Kill Practice"를 참조하세요.
변환 결과에서 , 우리는 주로 다음을 나열합니다:
1. 웹 애플리케이션은 모두 Go 바이너리 파일 배포 방법인 centos를 사용합니다. 서버는 종속성을 따를 필요가 없습니다(배포가 크게 용이함):
2. 저렴하고 실용적인 SLB 사용 솔루션 nginx 역방향 프록시를 피하고 고급 lua 스크립트도 피합니다.
3. 여기서는 redis 클러스터도 사용합니다. 서비스를 제공하기 위해 인터페이스를 사용하지 않습니다.
전체 기술 스택은 완료하려면 GO, RabbitMQ, Mysql만 알아야 합니다. 높은 동시성 플래시 판매 시스템은 우선 조작이 간편하다는 점에서 매우 매력적입니다. 위의 추론을 바탕으로 조정된 아키텍처를 아래에서 볼 수 있습니다(현재 독립형 GO는 아마도 도달할 수 있는 웹 인터페이스를 제공합니다). 최적화 없는 2WQPS):
1. 독립형 GO 인터페이스 권한 확인 성능이 4배 증가하고 배포 복잡성이 0에 가깝다고 할 수 있습니다(nginx 없음, redis 클러스터 없음, 운영을 위한 종속 환경 없음).
2. 트래픽 수준이 계속 증가함에 따라 웹서버와 수량관리 서버만 추가하면 되고, 기타 서비스 오버헤드는 없습니다. (확장성은 최대한 떨어진다고 할 수 있습니다.) 비용, 비례 증가 모델, 성능 병목 현상 없음);
3. 기존 솔루션과 비교하여 서버 수가 4배 이상 감소합니다(원본 기준으로 계산할 수 있음);
위 솔루션은 GO 언어로 되어 있습니다. GO는 배포가 쉽고 구현 용이성이 향상되어 GO가 웹 서비스를 제공하고 외부 종속성을 줄일 수 있습니다(웹 서비스 성능도 매우 높습니다). GO의 두 가지 Just-In-Time 기능을 사용하면 매칭 아키텍처를 빼서 전체적으로 플래시 세일 시스템을 구현하는 것이 어렵지 않습니다. 물론 Java와 PHP 모두 위 그림에서 조정된 플래시 세일 아키텍처를 구현할 수 있습니다. 그러나 여러 측면에서 볼 때, 대통령은 여전히 GO에 비해 분명한 이점을 가지고 있습니다.
계획을 되돌아보면 Go가 사고 패턴의 변화를 주도했고, Go의 단순함은 구현의 단순함으로 이어졌으며, 높은 효율성과 안정성은 아키텍처 최적화로 이어졌음을 느낍니다. 좋은 시스템 아키텍처는 간단하고 효율적이며 구현이 쉬워야 합니다.
위 내용은 Golang이 높은 동시성 즉시 종료를 만났을 때~의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!