JAVA 단일 인터페이스 최적화 실전 TPS 성능 10 배 향상

개술
최근 에 회사 의 주문 인터페이스 가 좀 느 려 서 사장 님 은 쌍 11 을 지탱 하지 못 할 까 봐 저 에 게 최적화 시 키 려 고 하 셨 습 니 다.그러나 전 제 는 크게 바 꾸 는 것 을 허락 하지 않 습 니 다.주문 인터페이스 가 너무 복잡 하기 때문에 너무 바 꾸 면 위험 할 까 봐 걱정 입 니 다.개발 원가 와 테스트 원가 도 매우 크다.이런 도 전적인 임무 에 대해 저 는 항상 좋아 합 니 다.문 제 를 해결 하 는 과정 에서 많은 것 을 배 울 수 있 기 때 문 입 니 다.
당시 에 나 는 단지 하단 인터페이스 가 느리다 는 것 을 알 았 을 뿐,아무 도 나 에 게 어디 가 느 린 지 알려 주지 않 았 다.즉,어떤 병목 이 하단 인터페이스 가 느 린 지 말 하 는 것 이다.사실 아무 도 몰라 도 괜찮아.왜냐하면 우 리 는 압력 측정 을 통 해 구체 적 인 병목 을 찾 을 수 있 기 때문이다.
이번 압력 측정 에서 발생 한 문제 와 어떻게 해결 하 는 지,그 동안 어떤 도 구 를 사 용 했 는 지 상세 하 게 소개 한다.
사용 하 는 도구 와 환경
공구.
  • Jmeter
  • JAVA 자체 테이프 의 jvisualvm
  • JMX
  • nmon
  • 환경.
  • 텐 센트 운 Mysql
  • 텐 센트 클 라 우 드 2 핵 4g 서버 1 대
  • 병목 을 찾다
    아래 는 쓰기 인터페이스 에 속 하 는데 대부분 상황 에서 병목 은 DB 리 이 고 프로그램 은 DB 자물쇠 의 방출 을 기다 리 고 있 을 것 이다.이 아 이 디 어 를 검증 하기 위해 서 는 Jmeterjvisualvm 을 사용 하여 검증 할 수 있다.
    서버 와 서버 의 JAVA 프로 세 스 를 감시 하기 위해 서 는 JMX 를 켜 야 합 니 다.JAVA 프로 세 스 가 시 작 될 때 다음 과 같은 몇 가지 인 자 를 추가 할 수 있 습 니 다.
    
    JMX_OPTS="-Dcom.sun.management.jmxremote.port=7969 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=xx.xx.xx.xx"
    nohup java ${JMX_OPTS} -jar xxxxx.jar
    
    Djava.rmi.server.hostnameJAVA 프로 세 스 가 있 는 서버 의 IP 주 소 를 입력 하 십시오.,-Dcom.sun.management.jmxremote.port=7969JMX 모니터링 포트 를 지정 합 니 다.여 기 는 7969 입 니 다.
    프로 세 스 를 다시 시작 한 후 로 컬(Window 10)jvisualvm 을 열 고 JMX 설정 을 추가 합 니 다.설정 이 성공 하면 스 레 드 의 tab 을 클릭 할 수 있 습 니 다.왜냐하면 우 리 는 스 레 드 dump 을 하고 스 레 드 의 집행 상황 을 관찰 해 야 하기 때 문 입 니 다.


    자,이제 우 리 는 Jmeter 을 사용 하여 다음 인터페이스 에 대해 압력 측정 을 할 수 있 습 니 다.먼저 50 스 레 드 로 동시에 누 를 수 있 고 실행 시간 은 1 분 입 니 다.

    압력 측정 과정 에서 스 레 드 dump 을 하 는 동시에 nmon 을 이용 하여 응용 서버 CPU 의 부하 상황 을 관찰 합 니 다.

    부하 가 낮 아서 스 레 드 를 100 으로 조정 한 후에 도 CPU 가 올 라 갈 수 없습니다.그러면 코드 에 자물쇠 가 있다 는 것 을 초보 적 으로 판단 할 수 있 습 니 다.
    dump 파일 을 관찰 한 결과 다음 과 같은 정 보 를 발견 할 수 있 습 니 다.
    - locked <22f6e7f3> (a com.mysql.cj.core.io.ReadAheadInputStream)
    - at com.sun.proxy.$Proxy231.reduceSkuStock(Unknown Source)
    이 lock 을 촉발 하 는 업무 코드 는 reduceSkuStock 방법 입 니 다.코드 를 읽 어 보 니 reduceSkuStock 이 큰 업무 에 포함 되 어 있 었 다.
    
    @Transactional(rollbackFor = {Exception.class})
     createOrder() {
     //1、    
     reduceSkuStock();
     //2、    
     insertOrder();
     //3、     
     。。。。
    }
    재고 기록 은 보통 하나의 독립 된 재고 표 가 존재 한다.주문 서 를 만 드 는 방법 은 큰 사무 이기 때문에 특정한 재고 기록 은 전체 createorder() 방법 이 실 행 된 후에 야 데이터 뱅 크 의 자물쇠 가 풀 려 날 수 있다.이 기간 에 다른 스 레 드 는 이 재고 기록 을 작성 할 수 없다.따라서 우 리 는 reduceSkuStock() 에서 한 가지 업 무 를 더 열 고 이 재고 기록 을 조작 한 후에 빨리 자 물 쇠 를 풀 어 성능 을 향상 시 킬 수 있 을 것 이다.업무 의 원인 으로 인해 단일 인터페이스 가 느 린 지 검증 하기 위해 서 우 리 는 createOrder() 방법의 사 무 를 직접 제거 하고 다시 한번 압력 을 가 하여 측정 할 수 있다.
    압력 측정 결과 에 따 르 면 다음 인터페이스의 TPS 이 배로 높 아 졌 고 CPU 도 많이 올 라 갔 지만 이상 적 이지 않 았 다.코드 에 다른 자물쇠 가 있 을 것 이다.다시 스 레 드 dump 을 만 들 었 는데 또 하나의 자 물 쇠 를 발견 했다.
    - locked <438be230> (a org.apache.http.pool.AbstractConnPool$2)
    - at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
    자 물 쇠 를 잠 그 는 코드 는 HttpClientexecute 방법 으로 이 방법 을 실행 할 때 HTTP 연결 을 얻 기 를 기다 리 고 있 었 다.소스 코드 를 살 펴 보 니 연결 탱크 를 사용 하지 않 고 취 했다.다음 코드 를 빨리 추가 하 세 요:
    
     PoolingHttpClientConnectionManager pool = new PoolingHttpClientConnectionManager();
     pool.setDefaultMaxPerRoute(400);
     httpClient = HttpClients.custom().setConnectionManager(pool).build();
    다시 한 번 테스트 한 후에 코드 안에 이미 자물쇠 가 없 는 것 을 발견 하 였 다.TPS 이 5 배 올 랐 다.하지만 앞으로 몇 가지 더 해 야 할 일이 있다.
    1.다음 인터페이스의 모든 SQL 을 인쇄 한 다음 에 explain 작업 을 한 다음 에 전체 표 에서 스 캔 한 문구 가 있 는 지,색인 을 사용 하지 않 은 SQL 문 구 를 살 펴 본다.
    2.다음 인터페이스 가 실 행 된 과정 에서 FULL GC 발생 하 는 횟수 를 관찰 합 니 다.
    3.응용의 MYSQL 연결 수 증가;
    자,이곳 에 도착 하면 우 리 는 앞으로 돌아 가 재고 문 제 를 해결 할 수 있 습 니 다.사장 이 크게 고 칠 수 없다 고 말 했 기 때문에 나 는 reduceSkuStock 방법 에 있어 서 다시 사 무 를 열 었 다.
    
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    reduceSkuStock(){}
    재고 작업 을 수행 하 는 스 레 드 를 실행 한 후 서둘러 줄 자 물 쇠 를 풀 어 줍 니 다.이렇게 하 는 것 도 위험 이 있다.바로 재고 공제 가 성공 한 후에 주문 이 실패 한 것 이다.그러나 이러한 상황 은 비교적 적 었 다.그 당시 의 하 도 급 인터페이스 에서 대부분의 업무 논 리 는 앞에서 판단 을 했 기 때문에 주문 을 삽입 하 는 코드 에 도 착 했 을 때 단독 insert 일 뿐 데이터 베 이 스 를 끊 지 않 으 면 하 도 급 실패 하 는 상황 이 발생 하지 않 았 다.
    개발 환경 에서 조정 을 거 친 후 단일 인터페이스의 TPS 가 3 배 정도 올 랐 다.물론 개발 환경의 데이터베이스 와 응용 서버 가 모두 비교적 나 빠 서 TPS 에 도 영향 을 미 칠 수 있다.당시 최적화 가 끝 난 후 생산 에서 압력 측정 을 실시 한 결과 TPS 이 10 배 올 랐 다.
    이것 은 하단 인터페이스의 논리 가 크게 바 뀌 지 않 는 상황 에서 최적화 방안 이다.일반적으로 재고 조작 은 단독 서비스 이 고 단독으로 최적화 할 수 있어 야 한다.단순 한 하단 논리 도 최적화 할 수 있다.
    총결산
    이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.더 많은 내용 을 알 고 싶다 면 아래 링크 를 보 세 요.

    좋은 웹페이지 즐겨찾기