Computer >> 컴퓨터 >  >> 프로그래밍 >> Ruby

과학자와 함께 중요한 Ruby on Rails 코드 리팩토링:입증된 접근 방식

소프트웨어 엔지니어에게 프로덕션 코드의 주요 부분을 검토하도록 요청하면 필연적으로 리팩터링이 필요한 세 가지 사항을 지적할 것입니다. 그렇다면 왜 그렇게 많은 불량하고 깨지기 쉬우며 오해를 받는 코드가 프로덕션 환경에서 계속 실행되고 있습니까?

대답은 간단합니다. 엔지니어들은 그것을 만지기를 두려워합니다. 리팩토링 작업이 식별되어 백로그에 추가되지만 현재 스프린트에 포함되는 경우는 거의 없습니다.

여기에는 여러 가지 이유가 있습니다. 코드는 몇 년 전에 팀을 떠난 엔지니어가 작성한 것일 수 있으며, 이를 완전히 이해하는 사람은 아무도 없습니다. 다른 경우에는 이 기능이 비즈니스에 매우 중요합니다. 어느 누구도 잠재적인 가동 중단이나 수익 손실에 대해 책임을 지고 싶어하지 않습니다.

이 게시물에서는 Scientist를 사용하여 중요한 Ruby 프로덕션 코드를 자신있게 마이그레이션, 리팩터링 및 변경할 수 있는 방법을 살펴보겠습니다.

하지만 먼저, 코드 문제를 파악하기 위해 테스트를 사용할 수 없는지 질문하실 수 있습니다.

이것이 바로 Rails 테스트의 목적이겠죠?

예, 아니오. 배포 전에 코드 변경에 대해 완전한 확신을 갖는 것이 어려운 경우가 많습니다. 단위 및 시스템 테스트를 통과했습니다. 가도 좋을 것 같죠?

현실은 현실 세계, 즉 생산을 대체할 수 있는 것이 없다는 것입니다. 데이터 품질이 좋지 않거나 테스트가 누락되면 어떻게 되나요? 새 소프트웨어가 생산 처리량을 처리할 만큼 충분히 잘 작동하는지 어떻게 알 수 있나요?

공공 서비스 팀은 때때로 "버그 호환성" 문제를 처리해야 한다는 사실을 깨닫습니다. 한동안 프로덕션에 버그가 존재하면 클라이언트는 일관되고 잘못된 동작에 의존하는 방식으로 코딩할 수 있습니다. 고객은 예상치 못한 방식으로 소프트웨어를 사용하는 경우가 많습니다.

과학자와 함께 Ruby 및 Rails의 생산 변화 관찰

프로덕션이 변경에 대한 확신을 얻을 수 있는 가장 좋은 장소라면 코드가 어떻게 작동하는지 관찰하는 것이 좋습니다. "프로덕션 테스트"라는 개념이 전통적인 소프트웨어 엔지니어링 관행과 모순되기 때문에 처음에는 무섭게 들릴 수 있습니다.

그러나 좋은 소식은 Ruby and Rails에서 Scientist gem을 사용하면 쉽고 안전하다는 것입니다. 과학자라는 이름은 주어진 가설을 검증하기 위해 실험을 수행하는 과학적 방법을 기반으로 합니다. 이 경우 우리의 가설은 새 코드가 해당 작업을 수행한다는 것입니다.

우리가 이 접근 방식을 안전하게 사용할 수 있는 이유는 실험이 여전히 기존 코드의 결과를 사용한다는 사실에 기인합니다. 새로운 코드는 정확성과 성능 모두를 관찰 및 비교 목적으로만 평가됩니다. 실제 데이터와 매개변수를 사용하여 성능을 평가함으로써 앞서 논의한 테스트 범위 문제를 완화합니다. 실험에서는 일반적으로 프로덕션에 미치는 영향을 최소화하기 위해 선택한 요청 샘플 속도를 평가합니다. 그러나 원하는 경우 모든 요청을 평가할 수 있습니다.

이제 Scientist가 추상화 방식으로 브랜치에서 어떻게 작동하는지 간단히 살펴보겠습니다.

Ruby's Scientist의 추상화 패턴별 분기

과학자의 접근 방식은 마틴 파울러(Martin Fowler)가 "점진적인 방식으로 소프트웨어 시스템에 대규모 변경"을 적용한다고 설명한 추상화 패턴에 의한 분기로 시작됩니다.

업데이트되는 코드를 격리하기 위해 추상화 계층을 도입합니다. 이 계층은 실험이 시스템의 나머지 부분에 투명하도록 사용할 구현을 결정합니다. 이 기술은 코드 경로를 결정하는 기능 플래그를 사용하는 것과 관련이 있습니다.

Github에서 시작된 Scientist gem은 실험을 통해 이 패턴을 구현합니다. 기존 코드를 컨트롤이라고 하며 새 구현이 후보입니다. 두 코드 경로 모두 무작위 순서로 실행되지만 제어 결과만 클라이언트에 반환됩니다.

과학자를 활용하여 Ruby 서비스 리팩터링

주어진 숫자에 대해 가장 큰 소인수를 반환하는 Ruby 서비스를 생각해 보세요. 필요한 후보 집합을 잘라내어 서비스 속도를 높이는 최적화 방법을 찾았다고 가정해 보겠습니다.

그러나 서비스 소유자는 버그가 발생하지 않았는지 확인하고 싶어합니다. 또한 성능 향상을 관찰하고 싶어합니다. 이 메서드를 호출하도록 클라이언트를 수정하여 다음 코드를 도입하세요.

 

현재로서는 use만 (제어) 표현식이 호출됩니다. 실험을 가치 있게 만들려면 맞춤 Experiment를 정의하세요. 클래스를 사용하여 활성화하고(아래 시간의 100%) 결과를 게시합니다(이 경우 로깅만). 과학자는 환상적인 데이터를 생성하지만 기본적으로는 아무 것도 수행하지 않습니다. 그 부분은 여러분의 몫입니다.

 

실험 결과는 기록되며 피드백을 바탕으로 시간이 지남에 따라 개선할 수 있습니다. 새 코드가 요구 사항을 충족하고 신뢰도가 높아지면 과학 코드를 새 구현에 대한 위임으로 대체하여 새 구현으로의 전환을 완료하세요.

LabTech, Ruby on Rails로 과학자 실험을 단순화

Rails 애플리케이션에서 LabTech gem을 사용하여 쉽게 과학자를 구성하고 결과를 처리할 수 있습니다.

AppSignal을 사용하는 애플리케이션은 Appsignal.instrument을 사용할 수 있습니다. 과학자 이벤트를 완료하는 데 걸리는 시간을 추적하는 사용자 정의 계측 도우미입니다. 다양한 실험 코드 블록을 둘러싸서 성능 타임라인에 이벤트가 나타나는지 확인하세요.

이제 LabTech로 돌아가 보겠습니다. 아래 웹페이지에서는 인수분해할 숫자만 허용합니다.

과학자와 함께 중요한 Ruby on Rails 코드 리팩토링:입증된 접근 방식

콘솔에 액세스할 수 있으면 쉽게 시작할 수 있습니다. 먼저 LabTech gem을 Gemfile에 추가하고 bundle install를 실행하세요. .

 

테이블에는 결과와 실험 구성이 저장되므로 데이터베이스 마이그레이션을 실행하세요.

 

LabTech 모듈이 사용된다는 점을 제외하면 추상화 계층은 동일합니다. 전체 코드는 GitHub에서 확인할 수 있습니다.

 

이 시점에서는 실험이 비활성화되므로 콘솔을 사용하여 모든 경우 또는 일정 기간 동안 활성화하세요.

 

이제 테스트를 실행할 수 있으며 실험이 평가됩니다. 결과를 텍스트로 보려면 Rails 콘솔에서 다음 명령 중 하나를 사용하세요.

 

몇 번의 성공적인 실행과 한 번의 제조 오류 후에 결과 요약이 어떻게 보이는지에 대한 예는 다음과 같습니다. 성공과 실패에 대한 개요는 물론 성능 차이를 보여주는 ASCII 차트도 있습니다.

 

Blazer gem은 결과를 쉽게 분석할 수 있는 좋은 방법을 제공합니다. 설치가 간단하며 테이블에 대해 SQL 쿼리를 실행할 수 있습니다. 여기 쿼리는 후보 구현이 원본보다 훨씬 빠르다는 것을 보여줍니다.

과학자와 함께 중요한 Ruby on Rails 코드 리팩토링:입증된 접근 방식

예제 소인수 분해 서비스에서 개선된 구현의 속도 향상은 고려해야 할 몇 가지 가능한 요소를 제거하는 경험적 방법에서 비롯됩니다. 더 높은 숫자를 고려하고 소인수를 찾으면 해당 인자로 나눈 목표 숫자에 도달한 후 검색을 중지할 수 있습니다. 새로운 코드 경로는 이를 달성하기 위해 하나의 문만 추가합니다.

또한 LabTech 테이블에 대한 Blazer 쿼리를 사용하여 실행 시간이 단축되는 것을 확인할 수 있습니다.

과학자와 함께 중요한 Ruby on Rails 코드 리팩토링:입증된 접근 방식

과학자의 활용 사례와 한계

과학자의 최적 사용 사례에는 부작용이 없는 검색, 계산 및 코드가 포함됩니다. 트랜잭션 업데이트나 이메일과 같은 외부 통합을 포함하는 코드는 해당 기능이 두 번 실행되기 때문에(이전 구현과 새 구현 모두) 모델에 완전히 맞지 않습니다.

이는 여러 사용 사례를 제거하므로 사소한 제한이 아닙니다. 그러나 실험이 성공에 중요한 경우 몇 가지 해결 방법이 있습니다. 부작용이 관련이 있는지 또는 중복이 문제인지 고려하십시오. 예를 들어, 어떤 경우에는 평가 중에 두 개의 이메일이 전송되는지 여부가 중요하지 않을 수 있습니다. 또 다른 옵션은 새 코드가 결과를 결정하지만 유지하지 않도록 하는 것입니다. 이렇게 하면 의미 있는 성능 비교가 불가능해집니다. 그러나 이를 통해 정확성을 확인할 수 있습니다.

다른 제한 사항은 과학자가 반환 값에 초점을 맞추는 데서 비롯됩니다. 경우에 따라 유효한 결과는 단순히 응답에 타임스탬프를 포함하는지 또는 특정 요인이 달라지는지 여부에 따라 시간이 지남에 따라 차이가 나타날 수 있습니다. 대부분의 경우 실험에서 사용자 정의 비교 논리를 작성하여 기본 문자열 비교 이상의 정확성을 확인할 수 있습니다.

마지막으로, LabTech의 한계는 이 글을 쓰는 시점에서 Rails 7로 포팅되지 않았다는 것입니다.

레일에서의 효과적인 과학자 실험을 위한 모범 사례

실험을 실행할 때 다음 항목을 고려하십시오:

  • Rails 프로젝트에서 과학자는 초기화 프로그램이나 Rails LabTech gem과 같은 래퍼에서 구성될 수 있습니다. 대부분의 Rails 애플리케이션에는 이미 데이터베이스가 있으므로 LabTech는 ActiveRecord를 활용하여 결과를 저장합니다.
  • 개발 및 테스트 속도가 느려지는 것을 방지하려면 준비 및 프로덕션 환경에서만 실험을 활성화하세요.
  • 제작에 미칠 수 있는 영향을 최소화하려면 일부 요청에 대해서만 실험을 실행하세요. LabTech는 실험을 활성화할 때 기본적으로 이를 선택적 매개변수로 지원합니다(처음에는 기본적으로 비활성화되어 있습니다). 순수 과학자를 사용하면 이 논리를 실험의 enabled?에서 쉽게 코딩할 수 있습니다. 방법입니다.
  • 일부 로직은 리소스 집약적이므로 낮은 샘플링 레이트부터 시작하는 것이 좋습니다. 결과에 대한 확신이 생기면 평가되는 요청의 비율을 높이세요.
  • 컨텍스트 속성을 추가하여 결과를 최대한 활용할 수 있습니다. 실험 컨텍스트는 게시된 결과에서 사용할 수 있는 데이터의 기호 키 해시로 설정될 수 있습니다. 예:
 

마무리:과학자와 함께 Ruby 앱을 관찰하고 모니터링하세요

이 게시물에서 우리는 Scientist gem을 사용하여 프로덕션에서 Ruby 코드를 변경, 마이그레이션 및 리팩터링하는 방법을 살펴보았습니다.

우리는 추상화 패턴에 의한 분기에서 과학자의 기원을 조사한 다음 리팩토링을 시작했습니다. 다음으로, LabTech가 결과 수집 및 과학자 구성에 어떻게 도움을 줄 수 있는지 살펴보았습니다.

그런 다음 마지막으로 몇 가지 모범 사례를 간략하게 설명하기 전에 Scientist의 몇 가지 제한 사항을 살펴보았습니다.

시스템에서 무슨 일이 일어나고 있는지 관찰하고 모니터링해야 합니다. 더욱 자신 있게 Ruby 코드에 중요한 변경 사항을 적용하려면 개발 프로세스에 Scientist를 통합하세요.

즐거운 코딩 되세요!

추신 Ruby Magic 게시물이 보도되는 즉시 읽으려면 Ruby Magic 뉴스레터를 구독하고 단 하나의 게시물도 놓치지 마세요!

과학자와 함께 중요한 Ruby on Rails 코드 리팩토링:입증된 접근 방식

대런 브로에머

Darren은 글을 통해 영감을 주고 복잡한 것을 이해하기 쉽게 만드는 것을 즐깁니다. 그의 관심 분야는 과학과 물리학, 그리고 두 가지를 모두 이해하기에 충분한 수학입니다. 그는 고품질 콘텐츠와 기술 솔루션을 만들고 가끔 이에 대해 트윗합니다.

Darren Broemmer의 모든 기사