저희 서비스는 식당이 주 고객이라서 매장 오픈 시간부터 트래픽이 몰리는데, 특히 11시부터 2시까지를 오전 피크로 보고 있습니다. AWS에서 운영 중인 API 서버군의 ELB Latency 지표는 일반적으로 130ms ~ 150ms 사이를 유지하고 있습니다.
여기서 ELB Latency란, “로드 밸런서가 등록된 인스턴스에 요청을 보낸 시간부터 인스턴스가 응답 헤더를 보내기 시작할 때까지 경과된 총시간(초)”을 의미합니다. (elb-cloudwatch-metrics 문서 참고)
그런데 오전 11시를 넘어서며 ELB Latency가 급격히 오르기 시작합니다.
지표를 확인한 순간 바로 롤백을 진행했지만 5분에서 10분 정도의 장애가 발생했습니다.
바로 AWS Premium Support에 case를 열어 어떤 일이 있었는지 문의를 해봤고, 내부 툴로 확인한 결과라며 답변을 주셨는데, 요약하면 이렇습니다.
서비스 투입되고 일정 시간 동안의 지표를 비교해본 결과
신 Redis로 교체 시
CPUUtilization: 15% -> 60% , EngineCPUutiliaztoin: 22% -> 99% , Total Cmds: 기존 대비 거의 두 배로 증가
HitRate는 투입 후 2시간에 걸쳐 0%에서 51%까지 상승
다시 구 Redis로 교체 시
CPUUtilization: 15% ~ 17% , EngineCPUutiliaztoin: 16% -> 18% , Total Cmds: 20% 증가
추가로 아래와 같이 제안도 주셨습니다.
가장 데이터가 적은 시간대에 Redis 교체를 고려
기존 Redis의 데이터를 백업 후 Restore 하여 6.2 버젼의 Redis를 시작(캐쉬데이터의 TTL 이 너무 짧지 않으면)
기존(cache.m5.large)보다 큰사이즈(cache.m5.xlarge 또는 그 이상)로 시작하였다가, 추후 Online scaling down을 통하여 크기를 줄이는 방법
아마도 RBAC을 적용하면 AUTH 명령을 추가로 실행하기 때문에 전체 커맨드 수가 많이 증가했을 것이고, 캐시가 비어 있는 새로운 서버를 띄우면서 HitRate가 지나치게 낮은 것이 문제가 됐을 거라고 판단했습니다.
2차 시도
기존 cache.m5.large(2vCPU)에서 cache.m5.xlarge(4vCPU)로 인스턴스 타입을 올렸습니다. 교체 전 스냅샷을 생성하고(10분 이내), 스냅샷으로부터 신규 Redis 서버를 생성했습니다(30분 이내)
이번에는 엔진 지표도 함께 볼 수 있게 모니터링 대시보드를 설정했습니다.
1차 장애 당시 신규 투입된 서버의 CPUUtilization, EngineCPUUtilization 지표
당시에는 EngineCPUUtilization를 보고 있지 않아서 100%까지 치고 올라가는 상황을 인지하지 못했었습니다.
그림에서 레디스 서버가 두 대인 것을 확인할 수 있는데, 두 대가 클러스터로 묶여(cluster mode 아님 주의) 한대가 장애가 날 경우를 대비하고 있습니다. 애플리케이션은 primary node만 바라보고 있습니다.
교체 시작!
Redis는 어쩐지 안정적인 것 같았습니다.
하지만 애플리케이션 서버 쪽 ELB Latency 지표는 200ms를 넘어가고 있었고, New Relic에서 확인한 연결 지연 시간(아래 그래프)이 심상치 않아 다시 롤백을 결정했습니다.
두 번의 실패 이후, 많은 반성을 하면서 ‘나는 뭘 모르고 있는지’ 찬찬히 돌아보기로 했습니다.
ElastiCache의 지표들을 이해해봅니다
EngineCPUUtilization
기존 사용하던 Redis 서버와 새로 띄운 서버는 몇 가지 지표에서 차이가 나긴 했지만, 모두 AWS Redis 지표 페이지에서 권고하는 수준 안에 있었습니다.
이 문제를 해결하기 위해 CPUUtilization와 EngineCPUUtilization는 물론이고, connection 관련 지표에 집중해서 모니터링하기로 했습니다.
첫 번째 장애 때의 그래프를 다시 가져와 봅니다.
CPUUtilization은 EngineCPUUtilization보다 낮았습니다.
CPUUtilization은 Redis 엔진(EngineCPUUtilization으로 표현)의 동작에 백그라운드 프로세스의 비용도 포함하기 때문에 이 값이 EngineCPUUtilization보다 낮은 게 이상하다고 생각했습니다.
Amazon ElastiCache for Redis 사용 설명서 > 어떤 지표를 모니터링해야 합니까? 문서를 보면, vCPU를 고려해서 알림 기준을 세워야 한다고 나와 있습니다.
일반적으로, 사용 가능한 CPU의 90%로 임계값을 설정하는 것이 좋습니다. Redis는 단일 스레드이기 때문에 실제 임계값은 노드 총 용량의 일부로 계산해야 합니다. 2개의 코어가 있는 노드 유형을 사용하는 경우를 예로 들어보겠습니다. 이 경우 CPUUtilization의 임계값은 90/2 또는 45%입니다.
당시 인스턴스 타입이 cache.m5.large였기 때문에 vCPU는 2개입니다. 위 그래프에서 CPUUtilization이 15% -> 60% 올라가는 것을 봤다면, 실제로는 30% ~ 100%구나라고 인지했어야 한다는 말입니다.
Amazon ElastiCache for Redis 사용 설명서 > Redis 지표에서의 설명에도 vCPU 2개까지의 소규모 호스트에선 CPUUtilization으로 보는 것이 더 낫다고 하는군요.
Redis 엔진 스레드의 CPU 사용률을 제공합니다. Redis는 단일 스레드이므로 이 지표를 사용하여 Redis 프로세스 자체의 로드를 분석할 수 있습니다. EngineCPUUtilization 지표는 Redis 프로세스에 대한 보다 정확한 정보를 제공합니다. 이 지표를 CPUUtilization 지표와 함께 사용할 수 있습니다. CPUUtilization은 다른 운영 체제 및 관리 프로세스를 포함하여 전체적인 서버 인스턴스의 CPU 사용률을 표시합니다. 4개 이상의 vCPU를 포함하는 대규모 노드 유형에는 EngineCPUUtilization 지표를 사용하여 조정 임계값을 모니터링하고 설정하세요.
ElastiCache 호스트에서는 백그라운드 프로세스가 관리형 데이터베이스 환경을 제공하기 위해 호스트를 모니터링합니다. 이러한 백그라운드 프로세스는 CPU 워크로드의 상당 부분을 차지할 수 있습니다. vCPU가 2개 이상(2를 초과하는)인 대규모 호스트에서는 이 점이 중요하지 않습니다. 하지만 vCPU가 2개 이하인 소규모 호스트에 영향을 줄 수 있습니다. EngineCPUUtilization 지표만 모니터링하는 경우 호스트가 Redis의 높은 CPU 사용률과 백그라운드 모니터링 프로세스의 높은 CPU 사용률로 오버로드되는 상황을 인식하지 못합니다. 따라서 vCPU가 2개 이하인 호스트의 CPUUtilization 지표를 모니터링하는 것이 좋습니다.
이 내용은 Amazon ElastiCache for Redis 사용 설명서 > 문제 해결(Troubleshooting) 문서에서도 언급됩니다.
CPU 사용량: Redis는 다중 스레드 애플리케이션입니다. 그러나 각 명령의 실행은 단일(주) 스레드에서 발생합니다. 이러한 이유로 ElastiCache는 CPUUtilization 및 EngineCPUUtilization 지표를 제공합니다. EngineCPUUtilization은 Redis 프로세스 전용 CPU 사용률을 제공하고 CPUUtilization은 모든 vCPU에 대한 사용량을 제공합니다. 두 개 이상의 vCPU가 있는 노드는 대개 CPUUtilization 및 EngineCPUUtilization의 값이 서로 다르며, 일반적으로 두 번째 값이 더 큽니다.
여기서 일반적으로 두번째 값이 더 크다고 했는데, 두번째 Redis 서버 교체 당시의 지표를 다시 가져와 볼까요?
이때는 EngineCPUUtilization 지표가 계속 낮았습니다. 이 현상에 대해 AWS 측에 문의를 해봤는데,
CPUUtilization = Redis 사용 CPU(EngineCPUUtilization) + others (Redis 외 프로세스) 사용 CPU로 이해하면 될 듯합니다. 즉, 해당 시점에는 Redis 서비스보다 others 서비스(예를 들면, 스냅샷으로 생성 이후 스토리지 최적화를 위한 작업 ?)에 CPU가 쓰이고 있었다고 봐야 할 거 같습니다. 문서에서 일반적으로 EngineCPUUtilization이 높다는 것은 해당 서버가 Redis 용이니까 일반적으로 그렇다는 의미로 보입니다.
화면에서 보이는 CPUUtilization 지표의 피크는 35%이고 이때도 일시 연결 오류가 발생했습니다. 그렇다면 어느 시점에 위험하다고 판단해야 했을까요?
이 당시 서버는 cache.m5.xlarge(4vCPU)이기 때문에, CPUUtilization 지표의 임계값을 90/4 즉, 20% 선으로 설정하고 20%가 넘으면 위험하다고 판단했어야 했을지도 모릅니다. AWS 측의 답변도,
네 , CPUUtilization 을 기준으로 본다면 22.5 % 를 임계값으로 계산해 볼 수 있겠습니다. Redis 가 단일 Thread 로 처리되므로 단일 CPU Core 가 90% 이상 사용되지 않는 것을 임계값으로 보라는 의미로 이해됩니다. 단, 4vCPU 이상의 대규모 노드 유형에는 Redis 엔진 코어 대한 사용률을 보고하는 EngineCPUUtilization 지표를 사용할 수 있습니다. 현재 사용하시는 인스턴스 유형 상 EngineCPUUtilization 으로 CPU 부하상황을 판단하는 것이 맞을 것 같습니다.
4vCPU의 대규모 노드라서 완전한 설명이 되는 건 아니지만, 아래와 같이 분석해볼 수 있겠습니다.
당시 redis 자체의 부하는 높지 않았다(EngineCPUUtilization 23%)
redis 이외의 프로세스에서 높은 CPU를 사용하고 있었고(22.5%를 초과) 부하의 원인이 되었다.
Amazon ElastiCache for Redis 사용 설명서 > 어떤 지표를 모니터링해야 합니까?에서 언급된 Redis 모니터링에 관한 글도 Redis 지표를 이해하는 데 많은 도움이 됩니다.
Roadrunner는 php-cli를 실행하고 GRPC를 통해 웹 서버에 연결합니다. FrankenPHP는 임시 SAPI를 사용하며 Apache의 mod_php와 더 비슷하고 Go 코드는 PHP 인터프리터를 라이브러리로 사용하며 모두 동일한 프로세스에 있습니다.
RoadRunner에는 작업자 모드만 있으며 호환되는 앱에서만 작동할 수 있습니다. FrankenPHP에는 모든 기존 응용 프로그램과 호환되는 “표준” 모드와 일부 코드 변경(예: RR)이 필요한 작업자 모드가 있습니다.
RoadRunner는 PSR-7 HTTP 메시지를 사용합니다. FrankenPHP는 일반 슈퍼글로벌과 스트림(일반 모드와 작업자 모드 모두)을 사용하며 처리된 각 요청 후에 재설정됩니다.
RoadRunner는 전투 테스트를 거쳤고 프로덕션 준비가 되었습니다. FrankenPHP는 실험적이며 아직 프로덕션에 사용할 준비가 되지 않았습니다.
FrankenPHP는 또한 Go 라이브러리로 사용되어 PHP를 Go 프로그램이나 서버에 통합할 수 있습니다(이론적으로는 FrankenPHP를 Go로 작성된 Traefik 또는 로컬 Symfony 웹 서버에 통합할 수 있어야 합니다).
krakjoe/parallel
krakjoe/parallel – PHP 8+를 위한 간결한 병렬 동시성 API. 확장은 병렬 처리에 대한 Golang의 철학을 따릅니다. “메모리를 공유하여 통신하지 마십시오. 대신 통신을 통해 메모리를 공유하십시오.” – 채널, 이벤트 및 Future와 같은 필요한 모든 브릭을 제공합니다.
cachewerk/relay
cachewerk/relay – PhpRedis 및 Predis와 같은 Redis 클라이언트이지만 PHP 확장으로 작성되었기 때문에 훨씬 빠릅니다. 저자는 캐싱을 위한 Laravel, WordPress 및 Magento 연동 기능도 제공합니다.
GitHub 페이지에 들어가보면 벤치마크 결과도 빠르게 확인할 수 있게 제공합니다. 주의 사항은,
참고: 우리는 New Relic의 열렬한 팬이지만 APM 에이전트를 활성화하면 Relay 속도가 크게 느려지고 벤치마크가 왜곡됩니다.
PhpRedis 역시 PHP 확장(extension)인데, Relay의 Documentation을 보면 APCu와 같은 shared in-memory cache라고 소개합니다. 모든 FPM worker 간 공유되는 PHP 메모리에 보관하기 때문에 더 빠르게 동작할 수 있습니다.
#[Service] classBlobStorageConsumer{ publicfunction__construct(publicreadonly BlobStorage $storage) {} // Some API methods that would interact with the BlobStorage instance }
phparkitect/arkitect
phparkitect/arkitect – 이 도구를 사용하면 PHP 코드베이스에 대한 아키텍처 제약 조건을 정의하여 CI에서 실행할 수 있습니다.
PHP 8.1이 필요하며 새로운 필터 및 유효성 검사, 작업 직렬화, 오류 핸들러, 대기열 및 콘솔 인터셉터, 이벤트 디스패처(PSR-14), 주입 가능한 열거형, 더 유연한 라우터, 최적화된 부트로더 및 더 나은 성능을 제공합니다.
Phalcon PHP Framework reached its major 5.0 release.
Phalcon PHP 프레임워크가 major 5.0 릴리스에 도달했습니다. Phalcon은 PHP 확장으로 제공되기 때문에 독특한 프레임워크입니다. 그러나 로드맵에 따르면 팀은 기존 모델로 전환하기로 결정했으며 다음 주요 릴리스는 PHP 패키지로 계획하고 있습니다. 5.0의 새로운 기능에 대한 자세한 목록은 업그레이드 페이지를 확인하십시오.
비대칭 가시성(Asymmetric Visibility) RFC는 좋은 RFC이고 유연하고 Readonly properties을 완전히 대체합니다. Brent가 우려하는 건 RFC 자체의 문제가 아니라 이 RFC가 readonly property를 완전히 대체하면서, readonly property가 사라질지 모르는 두려움이라고 합니다. 겨우 1년 전에 추가된 기능의 존속 여부가 불안해지는 것에 대한 우려이죠. 게다가 이미 작년에 Nikita의 유사한 아이디어에 관해 많은 논의를 했었고, readonly property가 use case의 90%는 커버할 수 있고 이 정도면 충분다고 결론이 났다고 합니다. 비대칭 가시성은 2년 전 readonly property에 관해 많은 논의를 했을 때 결정했어야 할 문제라고 생각한다고 합니다.
이 글의 마지막에는 readonly가 해결하지 못하는 문제를 연구가 이루어지고 있다고 그 예시를 소개하기도 합니다.
Increase code coverage successively by Andreas Heigl.
운영 체제나 프로그래밍 언어 런타임은 다양한 알고리즘을 사용하여 난수를 생성합니다. 동전 던지기처럼 실생활에서 볼 수 있는 진짜 난수 생성기에 비해 이런 의사(Pseudo) RNG(난수생성기, Random Number Generator)는 초기 “시드” 값에 의존하고 초기 시드 값과 알고리즘을 아는 것만으로도 난수의 전체 스트림을 예측하기에 충분합니다.
이 글에서 PHP 8.2 이후 제공되는 난수 생성기의 무작위성을 측정하기 위해 GD 확장을 사용해 임의의 X 및 Y 좌표에 단일 픽셀을 배치하여 이미지를 그립니다. 미리 결정된 시도 횟수에서 대부분 픽셀 분포가 균일한 이미지는 “진정한” RNG에 가까운 난수 생성기를 나타냅니다. 순수하게 시드 값을 기반으로 하는 값을 생성하는 RNG(예: Mersenne Twister)는 시드가 동일하게 유지되는 경우 동일한 출력을 생성해야 합니다.
Matthias Noback은 “그렇지 않다”고 결론지었습니다. Andreas Möller는 더 나아가 자신의 Enhancing types 블로그 게시물에서 그건 단순한(simple) type이라고 제안합니다.
바로 위 Matthias Noback의 글에서 DTO가 오직 원시(primitive) type의 값만 보유한다고 했는데, 그렇다면 DateTimeImmutable도 원시 type으로 분류할 수 있는지 고찰하는 글입니다.
이어 소개된 Andreas Möller의 글에서는 “정교한(sophisticated) 원시 type” 혹은 “단순한(simple) type”으로 부를 수 있을 것이라고 이야기 합니다. Ted M. Young은 이를 비제약 type이라고 표현하며 원시 type에 대한 집착을 버려라는 발표(Stop Obsessing About Primitives])를 하기도 했습니다. 글 마지막에 소개된 것처럼 원시 type에 집착하지 않고, 더 적절한 type을 찾아갈 필요가 있습니다.
읽기 전용 속성의 상속 문제을 수정합니다. 지금은 readonly는 private 범위에서만 설정할 수 있고 protected 범위에서는 설정할 수 없습니다.
다른 속성으로부터 재생성된 속성에 유용할 것입니다. 예를 들어, $o->setFirstName() 혹은 $o->setLastName()이 호출될 때마다 내부적으로 업데이트되는 public private(set) $fullName. 이는 향후 로드맵에 있는 접근자 hook에 적용될 수 있습니다.
DaveLiddament/sarb – 이 도구는 PHP 정적 분석기에 대한 기준점(baseline) 기능을 제공합니다(기준점 이후에 발생한 문제만 리포트). v1.5.0에서는 –clean-up옵션을 제공합니다. 여기에는 코드 품질을 점진적으로 개선하기 위해 수정해야 할 5가지 임의 문제가 나열되어 있습니다.
leafsphp/leaf
leafsphp/leaf – 웹 앱과 API를 빠르게 생성하기 위한 간단하지만 강력한 마이크로 프레임워크입니다.
솔직히, @symfony 가 커뮤니티 패키지를 수용하는 대신 시계를 만드는 것은 나를 슬프게 만듭니다. 그들은 NIH 증후군으로 계속 고통 받고 있습니다. 말 그대로 3(?) 시계 패키지와 동일한 인터페이스입니다. Symfony는 아마도 그들의 인기가 떨어지게 할 것입니다.
참고 : NIH 증후군(Not invented here syndrome)은 말 그대로 ‘여기서 개발한 것이 아니다.’(Not invented here)라는 의미로, 제3자가 개발한 기술이나 연구 성과는 인정하지 않는 배타적 조직 문화 또는 그러한 태도를 말한다. - 위키백과
Symfony가 왜 그렇게 하는지 전혀 읽지 않았지만 난 여기에 돈을 걸 것입니다. 1) 그건 사소합니다. 2) They don’t want to have to bug an outside rando with a day job and 1,000 other concerns to update PHP versions, fix bugs, etc. anytime something comes up.(역자 주: 해석 포기)
새로운 Laravel 프로젝트가 Vite를 사용하여 프론트엔드 자산을 번들로 제공한다는 소식을 전하게 되어 기쁩니다. Breeze와 Jetstream도 업데이트되었습니다. 🔥 Inertia Vue 또는 React와 함께 새로운 Breeze/Vite 스택을 사용할 때 번개처럼 빠른 핫 모듈 교체를 경험하십시오. ⚡
PHP 8.2 릴리스 프로세스를 시작하는 첫 번째 알파가 출시되었습니다. 업데이트는 정해진 일정에 따라 2주마다 릴리스되며 최종 릴리스는 11월 24일 경으로 예상됩니다. 기능 동결(feature freeze)은 7월 19일에 예상되며, 이는 일부 변경 사항이 여전히 릴리스에 포함될 수 있음을 의미합니다. 현재 가장 눈에 띄는 변화는 다음과 같습니다.
유사 유형이었던 null과 false에 추가하여 PHP는 이제 true 독립형 유형을 갖게 되며 이는 false에 대응합니다. 자세한 내용 은 이 변경 사항의 작성자인 George P. Banyard와 함께 하는 Derik Rethans의 PHP Internals News 팟캐스트를 들어보십시오.
Symfony 6.1은 3시간 전에 출시되었습니다. 방금 업그레이드 PR을 병합하고 프로덕션에 제공했습니다 🚀. 모든 것이 원활하게 실행됩니다. 애플리케이션은 ±10년이 넘었고 10k+ 클래스가 있으며 현재 20k rpm을 처리하고 있습니다. 모두 행복한 금요일 보내세요 😎 https://jobs.ticketswap.com
laravel/vite-plugi – Vite는 빠른 개발 환경을 제공하고 프로덕션용 코드를 번들로 제공하는 최신 프론트엔드 빌드 도구입니다. Laravel은 이제 개발 및 프로덕션용 asset을 로드하기 위한 공식 플러그인 및 Blade 지시문을 제공하여 Vite와 원활하게 통합됩니다.
hasinhayder/hydra
hasinhayder/hydra – 뛰어난 사용자 및 역할 관리 API와 함께 제공되는 Laravel 9x + Laravel Sanctum이 포함된 zero-config API boilerplate입니다.
Rust/Python/PHP/Node의 유명 패키지 레지스트리에서 소유자의 이메일이나 연결된 github 계정이 유효하지 않는 패키지를 탈취할 수 있음을 보여주고, 이메일 계정을 탈취하기 위해 도메인을 구입하거나 폐기된 GitHub 리포지토리를 다시 살렸다고 합니다(사실 폐기된 리포지토리명으로 생성은 안 되는데 아무렇게 만든 뒤 변경하는 방식으로는 가능했습니다). 이렇게 탈취한 뒤 악성코드를 심어 새로운 버전을 올리거나 최신 버전을 수정(이것도 문제)한 뒤 사용자들이 가져가게 합니다.
PHP-FIG has published a security related errata on PSR-7
이미 8.2에 accept된 [PHP RFC: Deprecate partially supported callables]의 범위를 확장하고자 하는 추가 RFC입니다. 이 RFC에 대한 자세한 내용은 Julliette와 함께하는 PHP Internals News 팟캐스트를 들어보십시오.
@ReactPHP is going to be even more awesome! 🚀 Currently boosting performance from 32000 to 39000 requests/s. This makes 18 billion requests per month on top 😎 On my laptop! On a single CPU core! 🔥 PHP scales! 💯
리팩토링이 필요한 파일을 검색합니다. 경로에 있는 각 PHP 파일을 검사하고 순환적 복잡성과 변경 기록을 기반으로 점수를 부여합니다.
PhpStorm에서는 여러 메트릭을 기반으로 리팩토링 후보를 찾는 built-in Refactoring Opportunities 검사를 활성화할 수 있습니다. 여기에서 자세히 알아보십시오.
역자 주 : PhpStorm 2021.2부터 들어왔지만, IntelliJ에 PHP plugin을 사용하고 계신 분이면 이 옵션이 안 보일 수 있습니다. 이때는 PHP Architecture plugin을 추가로 설치하시면 됩니다. 아래 플러그인으로도 비슷한 효과를 보실 수 있습니다.
“언젠가 여러 구현을 가질 수 있기 때문에 인터페이스를 선언하고 있습니다.”라고 말하는 사람이 있죠. 물론입니다. 그 날이 오면 Extract Interface 리팩토링을 수행하세요. 대부분의 IDE는 한 번의 클릭으로 이를 수행합니다. 그때까지 인터페이스를 삭제하십시오.
내장된 종속성의 업데이트로 인한, Windows 사용자를 위한 보안 릴리스입니다. Windows가 아닌 사용자의 경우 일반적인 버그 수정 업데이트일 뿐입니다. PHP 7.3의경우 보안 문제가 있더라도 업데이트가 더 이상 릴리스되지 않습니다. PHP 7.3 또는 PHP 5.x 버전을 계속 사용하고 있다면 가능한 한 빨리 업데이트하는 것이 좋습니다.
Symfony 팀은 다가오는 Symfony 6.1 릴리스에서 최소 필수 PHP 버전을 8.1로 올렸습니다. Drupal 10 과 Laravel 10에서도 동일한 변화가 이루어졌습니다.
또한 최근 출시된 Ubuntu 22.04 LTS 에는 PHP 8.1이 사전 설치된 상태로 제공됩니다.
최근에 발견된 취약점도 있었습니다. CVE-2022-24828: Composer Command Injection. composer.json에 있는 URL에 명시적으로 나열된 Git 또는 Mercurial 리포지토리를 제어하는 공격자는 특수하게 조작된 분기 이름을 사용하여 composer 업데이트를 실행하는 시스템에서 명령을 실행할 수 있습니다.
composer self-update를 실행하여 Composer가 최신 상태인지 확인하십시오.
PHP 8.1은 PHP RFC: Readonly properties 2.0을 통해 읽기 전용 속성에 대한 지원을 추가 했습니다. 그러나 특히 많은 속성을 포함하는 경우 (준)불변 클래스를 선언하는 것은 여전히 쉽지 않습니다. 따라서 이 RFC는 readonly 클래스에 대한 지원을 추가할 것을 제안합니다.
최적화된 데이터 구조를 PHP에 추가하려는 계획의 일환으로 첫 번째 제안이 준비되었습니다. Deque – 이것은 양방향 대기열입니다. 즉, 시작과 끝에서 항목을 추가 및 제거할 수 있습니다. SplQueue또는 SplDoublyLinkedList 대신 사용하여 성능을 향상시키고 메모리 소비를 줄일 수 있습니다.
A function to get the memory size for any variable that promises to be more accurate compared to memory_get_usage(). Requires PHP 7.4 or higher with FFI.
Matthias Verraes의 Named Constructors in PHP에서 출발하는 글입니다. 기본 생성자 하나만 제공되는 PHP에서 constructor 대신 도메인을 충분히 표현하는 static method로 overloading이 안 되는 문제를 보완하는 방식입니다.
배열을 합치기 위해 loop 안에서 여러번 array_merge를 호출하지 말고, array_merge가 여러 인자를 받을 수 있으므로 한번에 실행하라고 조언합니다. 여러 인자를 받을 수 있는 implode(), array_sum()도 마찬가지의 효과가 있습니다. 최신 버전의 PHP를 쓰기만해도 성능 개선 효과를 볼 수 있습니다.
All the Dynamic Syntaxes in PHP – Good source for interview questions?
PHP 생태계를 위한 오픈 소스 공급망 보안 해결. Paragon IE 사람들의 계획(initiatives)에 대한 흥미로운 게시물입니다. 그들은 이제 앱과 종속성을 안전하게 업데이트하기 위해 Gossamer라는 도구를 개발하고 있습니다. 이전에는 PHP 코어에 libsodium을 도입 하고 JWT에 대한 더 안전한 대안인 Paseto를 만들고 다른 도구도 개발했습니다.
PHP로 구현하는 흥미로운 프로젝트를 시도해보세요 : mrsuh/php-generics. 흥미롭게도 Reddit 에서는 성능을 위해 PHP에서 런타임 유형 검사를 삭제하는 것에 대한 토론이 있었습니다. 위의 도구는 타입 제거 방식(Type erasure)을 구현하므로 이론적으로는 다음과 같이 성능 관련 사례로 사용할 수 있습니다 : composer dump-generics --type=type-erasure.
PHP에 연산자 오버로딩을 추가하자는 제안이 투표를 통과하지 못했습니다. 그러나 저자 Jordan LeDoux와 함께하는 PHP Internals News 팟캐스트에서 자세한 내용을 들어볼 수 있습니다. Jordan은 또한 PHP용 RFC를 만드는 방법에 대한 매우 철저한 지침을 발표했습니다.
Symfony 관련 작업 외에도 이 도구에는 MAMP/WAMP의 최신 대안으로 사용할 수 있는 로컬 서버가 포함되어 있습니다. 여러 버전의 PHP를 지원하고(각 프로젝트에서 자체적으로 지정할 수 있음) Docker, 로컬 도메인 및 자동화된 HTTPS와 통합됩니다. 이 도구는 Go로 구현되며 Linux, macOS 및 Windows에서 사용할 수 있습니다.
이 글에서는 지연된 조인으로 offset/limit이 적용될 때까지 요청된 열에 대한 액세스를 연기하는 기술입니다.
select*from contacts -- The full data that you want to show your users. innerjoin ( -- The "deferred join." select id from contacts -- The pagination using a fast index. orderby id limit 15offset150000 ) as tmp using(id) orderby id -- Order the single resulting page as well.
이 글에서는 이 아이디어를 Laravel로 구현하는 예제와 더 나은 성능을 위한 MySQL 튜닝 아이디어 그리고 많은 이들의 성능 개선 간증이 이어집니다.
PHP에서 정적 분석이 중요한 이유와 이에 대해 열광하는 이유에 대해 간단히 읽고 싶다면 우리는 런타임 유형 검사가 필요하지 않습니다라는 블로그 게시물을 확인할 수 있습니다.
The PHP foundation
2개월 전, PHP 세계는 2021년의 가장 큰 뉴스일 수도 있는 꽤 큰 뉴스를 받았습니다. 가장 활동적인 핵심 유지 관리자 중 한 명인 Nikita가 LLVM 작업을 위해 자리에서 물러나지만 동시에 PHP core 개발을 지원할 수 있게 몇몇 대기업이 지원하는 새로운 이니셔티브도 생겼습니다.
요컨대, PHP core 개발 자금을 지원하는 유일한 목표를 가진 비영리 PHP Foundation이 있습니다. 이 이니셔티브는 이미 프로젝트에 10만 달러를 약속한 JetBrains가 주도합니다. 다른 많은 사람들과 함께 이제 $329,920.75를 모았습니다. 좋은 시작!
이 글을 번역하는 시점에는 $386,384.93 USD, 연간 추정 예산은 $468,509.68 USD입니다.
Packagist는 이제 300만 개 이상의 등록된 버전과 300,000개 이상의 패키지가 있습니다. 보시다시피 생태계는 계속 성장하고 성장하며 2022년에도 다르지 않을 것입니다.
최근에 Packagist는 500억 회 이상의 설치(install)를 처리하는 이정표를 통과했습니다. 축하해요 Packagist!
Async PHP
Async 커뮤니티의 흥미로운 개발 중 하나는 Amp와 ReactPHP의 개발자가 함께 모여 Revolt PHP라는 fiber 호환 이벤트 루프 구현을 만들었다는 것 입니다.
Serverless PHP
Matthieu Napoli는 PHP 개발자에게 이 비교적 새로운 PHP 사용 방법에 대해 교육하는 것을 그의 사명으로 삼고 있으며 꽤 잘하고 있는 것 같습니다. 서버리스 PHP를 쉽게 만들기 위한 그의 오픈 소스 프로젝트인 Bref를 확인 하거나 2022년 서버리스 PHP에 대한 그의 visual course을 확인할 수 있습니다.
PHP-FIG는 PHP Evolving Recommendations의 아이디어를 승인했습니다. PSR 표준 외에도 영구적으로 변경 및 보완할 수 있는 권장 사항인 PER이 있습니다. 예를 들어 코드 스타일의 경우 새로운 언어 기능을 반영하는 새로운 규칙을 추가할 수 있습니다.
“Vulnerability” (not) in PHP to bypass disable_functions
한 연구원이 최근 php.ini의 disable_functions 지시문에 의해 설정된 제약 조건을 우회하는 방법을 발표했습니다.
disable_functions를 사용하여 PHP 스크립트에서 특정 기능의 사용을 금지할 수 있습니다. 예를 들어 system, exec, proc_open 및 shell_exec가 외부 프로그램에 대한 호출을 차단하는 것을 금지할 수 있습니다. (그건 그렇고, eval()은 함수가 아니라 언어 구조이기 때문에 금지할 수 없습니다.)
disable_functions는 보안 기능이 아니며 보안을 위해 그것에 의존하는 것은 나쁜 생각이기 때문에 우회 문제는 취약점이라고 할 수 없습니다.
이게 PHP의 보안 문제가 맞다고 하는 글에 Nikita Popov(aka nikic)가 reddit에 댓글을 남겼습니다. 많은 스크립트 언어들처럼 PHP 구현이 임의의 공격자가 제어하는 코드를 안정적으로 샌드박싱하는 것이 주요 목표는 아니며, 보안 문제인지 여부는 위협 모델(threat model)에 따라 판단할 수 있는데 서버에 올라간 PHP 프로젝트에 관한 한 원격 공격자를 위협 모델로 상정한다고 합니다. 아래 내용에서 정확한 표현으로 확인하세요.
Whether something is a security issue depends on your threat model. As far as the PHP upstream project is concerned, our threat model is a remote attacker. We consider the case where the attacker has ability to execute arbitrary PHP code on the server a lost cause.
Of course, for a shared hosting provider that does not use any OS-level separation between clients, this is a security issue. As far as the PHP project is concerned, this is a fundamentally insecure deployment method. You may use it at your own risk.
This is a matter of practicality, because the PHP implementation is very far removed from reliably sandboxing arbitrary attacker-controlled code. There are some languages that have this as a hard design constraint (the most important being JavaScript), but for other scripting languages this is not a primary goal (definitely not for PHP, and I would strongly suspect not for Python or Ruby either, though I’m not sure on that count).
If we wanted to move in that direction, the first step would be to promote all remaining engine notices/warnings to exceptions, because there is a large class of interrupt vulnerabilities caused by them (to the point that addressing other issues would be somewhat “pointless” from a security perspective). One of my bigger regrets for PHP 8.0 is that we did not make undefined variables an exception.
PHP에서 보안 문제로 간주되는 것과 그렇지 않은 것에 대해 자세히 알아보십시오: wiki.php.net/security. 이 문서에선 다음과 같은 문제가 보안 문제 버그로 분류됩니다.
George Peter Banyard는 타입 선언에서 null을 사용하는 기능을 추가할 것을 제안합니다.
첫째, 이것은 PHP의 타입 시스템의 완전성에 대한 누락된 부분입니다. mixed 타입과 never 타입이 추가됐고, union과 intersection이 있지만 unit 타입은 누락되었습니다.
둘째, 이 타입은 타입 힌트에 대한 일부 엣지 케이스를 다루고 정적 분석을 개선합니다. 예를 들어 현재로서는 유사타입(pseudotype)인 false를 union에서 사용할 수 있지만 함수가 false|null을 반환하도록 지정할 수는 없으며 bool|null만 반환할 수 있습니다.
Symfony 5.4 및 6.0은 11월에 출시될 예정입니다. 차이점은 Symfony 5.4에는 더 이상 사용되지 않는 기능이 모두 포함되지만 Symfony 6.0에서는 모두 제거된다는 것입니다. 또한 Symfony 5.4 및 6.0 모두 가능한 경우 모든 메서드 속성, 인수 및 반환 값에 PHP 유형 선언이 추가됩니다.
없는 것보다는 나으니 아무거나 테스트하려는 사람들을 말리며, 테스트를 작성하지 말고 좋은 테스트를 작성하라고 합니다. 그렇게 하는 동안 테스트 작성이 재미있고 쉽고 효과적인지 확인하라고 하네요. 켄트백은 “테스트는 두려움을 지루함으로 변화시켜주는 프로그래머의 돌이다.”라고 했는데 말이죠…
어쨌든 이를 위해 다음에 투자해야 한다고 합니다.
특정 테스트를 매우 빠르게 실행하는 데 도움이 되는 테스트 도구
빠른 결과를 제공하는 테스트
다른 데이터가 제공될 때 코드가 어떻게 동작하는지 보여주기 위해 더 많은 테스트 케이스를 추가하는 것은 정말 저렴해야 합니다.
이런 게 “클래스 하나에 테스트 하나” 규칙이나 request 날리고 DB 확인하는 테스트(make-request-then-look-in-DB)보다는 나을 거라고 합니다.