apache http client의 타임아웃 관련(기본 값 등) - 버전마다 틀릴 수 있으며 아래는 4.5.3 기준





* 요약 

 - 0으로 셋팅하면 무한이고, 음수로 셋팅하면 OS 시스템의 기본값을 따른다.

 - 리눅스 계열에서 시스템 기본값은 net.ipv4  timeout time wait쪽을 살펴보면 되는 것 같음

      




[참고 - 소스]


 /**

     * Determines the timeout in milliseconds until a connection is established.

     * A timeout value of zero is interpreted as an infinite timeout.

     * <p>

     * A timeout value of zero is interpreted as an infinite timeout.

     * A negative value is interpreted as undefined (system default).

     * </p>

     * <p>

     * Default: {@code -1}

     * </p>

     */

    public int getConnectTimeout() {

        return connectTimeout;

    }

/**

* Request Checker

*  - Redirect

*

* @param modelAndView

* @return

*/

private boolean isRedirect(ModelAndView modelAndView) {

return modelAndView.getView() instanceof RedirectView || modelAndView.getViewName().startsWith("redirect:");

}

  •  요약
    • G1 GC worst-case에서 향상 목적
    • JDK9부터 기본 GC가 G1으로 변경되었는데, concurrent GC에서 full GC가 발생 할 수 있음. 
    • G1 GC의 알고리즘 mark-sweep-compact를 병렬로 수행하도록 변경되었으며 -XX:ParallelGCThreads 옵션을 사용해서 스레드 수 조정 가능


JEP 307: Parallel Full GC for G1

Owner Stefan Johansson
Type Feature
Scope Implementation
Status Closed / Delivered
Release 10
Component hotspot / gc
Discussion hotspot dash gc dash dev at openjdk dot java dot net
Effort M
Duration M
Reviewed by Mikael Vidstedt
Endorsed by Mikael Vidstedt
Created 2017/01/17 11:40
Updated 2018/03/29 07:39
Issue 8172890

Summary

Improve G1 worst-case latencies by making the full GC parallel.

Non-Goals

Match the performance of the parallel collector's full GC for all use cases.

Motivation

The G1 garbage collector was made the default in JDK 9. The previous default, the parallel collector, has a parallel full GC. To minimize the impact for users experiencing full GCs, the G1 full GC should be made parallel as well.

Description

The G1 garbage collector is designed to avoid full collections, but when the concurrent collections can't reclaim memory fast enough a fall back full GC will occur. The current implementation of the full GC for G1 uses a single threaded mark-sweep-compact algorithm. We intend to parallelize the mark-sweep-compact algorithm and use the same number of threads as the Young and Mixed collections do. The number of threads can be controlled by the -XX:ParallelGCThreads option, but this will also affect the number of threads used for Young and Mixed collections.

Testing

  • Full GC time analysis to ensure that the full GC times have improved. Looking at benchmark scores will probably not be good enough since G1 is designed to avoid full GCs.
  • Runtime analysis using VTune or Solaris Studio Performance Analyzer to find unnecessary bottlenecks.

Risks and Assumptions

  • The work is based on the assumption that nothing in the fundamental design of G1 prevents a parallel full GC.
  • The fact that G1 uses regions will most likely lead to more wasted space after a parallel full GC than for a single threaded one.

개인적으로 API를 만들어서 AWS EC2에서 서비스 중인 사용처들에게 제공 중인데 이 때 JWT인증을 사용 중. 관련하여 메모


1. JWT토큰 인증이란?

AWS의 인스턴스는 IP가 변경될 수 있기에 기존의 IP인증 방식으로는 API를 사용할 수 없습니다.(Elastic ip)를 사용하면 고정되기는 함)
이처럼 IP인증 방식을 사용하기 어려울 때 사용하는 인증 방식입니다.

2. JWT 토큰의 포맷 및 규약은?

JWT(Json Web Token)이라는 RFC 7519 표준의 토큰방식을 따릅니다.(http://jwt.io/)
Header(알고리즘과 토큰타입), Payload(데이터), Verify signature(변조검증)로 구성되어 있으며
Header와 Payload는 base64로 디코딩시 내용을 확인 가능합니다.

토큰인증 방식을 사용하시려면 HTTP 헤더에 서비스코드와 인증토큰 2가지 값을 전달해주셔야합니다.

3. 디코딩시 내용을 볼 수 있는데 보안 문제는 없는건지?

API 인증 용도의 토큰은 유저정보 등의 노출되면 안되는 정보가 없기에 디코딩되도 무방합니다.
또한, Verify Signature가 존재하여 HMAC로 토큰을 검증하기에 Header와 Payload는 변조가 불가능합니다.
(필요시 토큰 자체를 암호화할 수도 있기는하지만, 필요성이 없는 작업에 암복호화를 위한 서버 리소스를 사용할 필요가 없어서 진행 안함 , 필요시 AES256으로 암복호화 처리 중)

4. 토큰 인증방식의 성능은?
성능 테스트결과 기존 IP인증 방식과 동일한 TPS를 보였으며 경우에 따라서는 더 좋은 결과를 나타냈습니다.

5. 토큰을 발급 받으려면?

"따로 제공하는 인증토큰 발급 API"를 이용해서 발급 받을 수 있습니다.
해당 API는 HTTPS로 통신하며 사전에 전달받은 서비스코드와 토큰발급용 암호 2가지 값이 필요합니다.

6. 사용 중 토큰이 만료되었다고 실패가 발생하면?
토큰을 재 발급 받아서 해당 API를 다시 호출하셔야 합니다.

7. 토큰은 서비스별로 유일한지?
유일하지 않습니다. 여러개일 수 있습니다.

8. 토큰이 여러개일 수 있는 이유는?

API를 호출하는 서버는 여러개일 수 있어서 특정 토큰 1개만 허용하게되면 동시성 이슈가 발생할 수 있습니다. 
또한, 토큰 1개만 유지할 경우 제공 및 사용측에서 글로벌캐쉬 등을 사용해야해서 복잡해집니다.
이를 해결하기 위해 토큰은 여러개 발급 가능하도록 허용해뒀습니다.


/**

 * Spring boot에서 셧다운 이벤트 발생시 리스너 샘플

 * 

 * @author 

 */

@Component

public class StopListener implements ApplicationListener<ContextClosedEvent> {

 

@Override

public void onApplicationEvent(final ContextClosedEvent event) {

System.out.println("셧다운 호출");

}

}

 

 


1. 목적 : 서버가 어떤 웹서버를 사용하는지 감춰서 해킹을 시도하는 유저에게 정보 제공을 줄임

2. 방법

 -  proxy_pass_header Server; 를 추가


* 응답 헤더 server: nginx 가 없어짐

추가

  • AWS CloudFront를 사용할때 http header를 이용해서 특정 국가를 nginx를 이용해서 차단하고 싶을때
if ($http_cloudfront_viewer_country = "CN") {
  return 403;
}

 

rate limit에 해당될때 json으로 리턴하고 싶을때 샘플

error_page 429 /429.json;
    location /429.json {
        add_header 'Content-Type' 'application/json charset=UTF-8';
        return 429 '{"success":false, "errorCd":"RATE_LIMITED","msg":"Too Many Requests(rate limit nginx)"}';
    }

 

중국쪽 봇 등으로 짜증날때 nginx로 전체 인입허용 트래픽을 빠르게 조절할때 사용할 목적으로 간단하게 메모해둡니다.

 - 아래 내용은 추후 복/붙 가능한 형태로 좀 수정해둘 예정

 

http블럭에

limit_req_zone $binary_remote_addr zone=myLimit:10m rate=10r/s;

 

location 블럭안에

limit_req zone=myLimit burst=5 nodelay;


limit_req_zone

예) limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

  • context: http
  • key: 요청량 제한 단위 지정 (예. server_name, remote_addr, uri 등) $server_name을 지정하면 모든 트래픽에 대해 요청량을 제한함
  • zone: 요청량 기록을 위해 사용하는 Key:Value 가 저장될 Shared Memory 크기.
    • 주의: IP 단위로 요청량을 제한 할경우 충분히 큰 값을 설정하지 않으면 메모리 부족 발생할 때 모두 503에러
  • rate: 허용할 request per second 값으로 10r/s를 설정하면 NGINX는 100ms 마다 1개의 요청을 처리

 

limit_req 

예) limit_req zone=mylimit burst=10 nodelay;

  • context: http > server > location
  • burst: key에 설정한 요청량보다 초과된 요청량을 수용하는 크기로 대기큐.
    • rate를 10 rps 로 설정했을 때 100ms 안에 10개의 요청이 들어오면 1개만 처리되고 나머지 9개의 요청은 503 에러가 발생하는 데 이 때 해당 에러를 완화하기 위해서 burst옵션을 사용
    • nodelay: 요청이 rps 에 지정된 시간보다 빨리 처리되었을 때 rps에서 지정한 시간을 기다리지 않고 burst queue에 있는 다음 요청을 바로 처리. 해당 옵션을 사용하지 않는다면 burst queue가 비워질 때까지 새로운 요청은 모두 503 응답

limit_req_dry_run 

  • on: 실제로 제한은 하지 않고 로그를 남김
    • 꼭 해당 기능을 이용해서 라이브 환경의 적절한 수치를 확인하고 적용하는게 좋음
      • 로그에 $limit_req_status 설정 추가 필요

 

기타

 - 제한에서 제외할 IP설정 방법

geo $apply_limit {
    default         $binary_remote_addr;
    10.10.0.0/16    '';                   # 내부 네트워크 대역 10.10.*.* 은 access limit 사용안함
    211.33.188.246  '';                   # 외부의 특정 IP 211.33.188.246 는 access limit 사용안함
}

...
...

limit_req_zone $apply_limit zone=depend_rate_limit:10m rate=10r/s;

...

 

geo 모듈을 사용해서 client ip 를 확인해서 $apply_limit 이라는 변수를 새롭게 할당했다. 10.10.. 대역 이거나, (내부 네트워크 대역인 경우), 외부의 특정 211.33.188.246 인 경우에는 빈값이 지정된다.

 

이렇게 하고 나서 limit_req_zone 에 정의한 $apply_limit 변수를 사용하면, 예외로한 IP 에 대해서는 접속제한이 동작하지 않는다.


참고 링크

 - https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-http/

 - https://bactoria.github.io/2020/01/19/Nginx%EC%9D%98-limit_req-%EB%AA%A8%EB%93%88-%EC%82%AC%EC%9A%A9%EA%B8%B0/

 - https://findstar.pe.kr/2018/06/24/nginx-rate-limiting/

 - https://serverfault.com/questions/177461/how-to-rate-limit-in-nginx-but-including-excluding-certain-ip-addresses

'기타' 카테고리의 다른 글

if kakao day 2 후기  (0) 2019.09.02
메모 - 아파치 OFBIZ  (0) 2019.05.23
SNS 공유시 캐시 처리 및 validataor 등  (0) 2018.09.14
웹 취약점 진단도구 메모  (0) 2018.07.09
좋은 코드 작성하기 참고  (0) 2018.06.29

개인적인 생각과 비슷한 부분이 많아서 메모


참고 : alibaba mysql rules(with java) 

 - https://github.com/alibaba/Alibaba-Java-Coding-Guidelines#3-mysql-rules




Table Schema Rules

1. [Mandatory] Columns expressing the concept of True or False, must be named as is_xxx, whose data type should be unsigned tinyint (1 is True, 0 is False).

Note: All columns with non-negative values must be unsigned.

2. [Mandatory] Names of tables and columns must consist of lower case letters, digits or underscores. Names starting with digits and names which contain only digits (no other characters) in between two underscores are not allowed. Columns should be named cautiously, as it is costly to change column names and cannot be released in pre-release environment.

Positive example: getter_admin, task_config, level3_name
Counter example: GetterAdmin, taskConfig, level_3_name

3. [Mandatory] Plural nouns are not allowed as table names.

4. [Mandatory] Keyword, such as descrangematchdelayed, etc., should not be used. It can be referenced from MySQL official document.

5. [Mandatory] The name of primary key index should be prefixed with pk_, followed by column name; Unique index should be named by prefixing its column name with uk_; And normal index should be formatted as idx_[column_name].

Note: pk means primary key, uk means unique key, and idx is short for index.

6. [Mandatory] Decimals should be typed as decimalfloat and double are not allowed.

Note: It may have precision loss when float and double numbers are stored, which in turn may lead to incorrect data comparison result. It is recommended to store integral and fractional parts separately when data range to be stored is beyond the range covered by decimal type.

7. [Mandatory] Use char if lengths of information to be stored in that column are almost the same.

8. [Mandatory] The length of varchar should not exceed 5000, otherwise it should be defined as text. It is better to store them in a separate table in order to avoid its effect on indexing efficiency of other columns.

9. [Mandatory] A table must include three columns as following: idgmt_create and gmt_modified.

Note: id is the primary key, which is unsigned bigint and self-incrementing with step length of 1. The type of gmt_createand gmt_modified should be DATE_TIME.

10. [Recommended] It is recommended to define table name as [table_business_name]_[table_purpose].

Positive example: tiger_task / tiger_reader / mpp_config

11. [Recommended] Try to define database name same with the application name.

12. [Recommended] Update column comments once column meaning is changed or new possible status values are added.

13. [Recommended] Some appropriate columns may be stored in multiple tables redundantly to improve search performance, but consistency must be concerned. Redundant columns should not be:
  1) Columns with frequent modification.
  2) Columns typed with very long varchar or text.

Positive example: Product category names are short, frequently used and with almost never changing/fixed values. They may be stored redundantly in relevant tables to avoid joined queries.

14. [Recommended] Database sharding may only be recommended when there are more than 5 million rows in a single table or table capacity exceeds 2GB.

Note: Please do not shard during table creation if anticipated data quantity is not to reach this grade.

15. [For Reference] Appropriate char column length not only saves database and index storing space, but also improves query efficiency.

Positive example: Unsigned types could avoid storing negative values mistakenly, but also may cover bigger data representative range.

ObjectAgeRecommended data typeRange
humanwithin 150 years oldunsigned tinyintunsigned integers: 0 to 255
turtlehundreds years oldunsigned smallintunsigned integers: 0 to 65,535
dinosaur 
fossil
tens of millions years oldunsigned intunsigned integers: 
0 to around 4.29 billion
sunaround 5 billion years oldunsigned bigintunsigned integers: 0 to around 10^19

Index Rules

1. [Mandatory] Unique index should be used if business logic is applicable.

Note: Negative impact of unique indices on insert efficiency is neglectable, but it improves query speed significantly. Additionally, even if complete check is done at the application layer, as per Murphy's Law, dirty data might still be produced, as long as there is no unique index.

2. [Mandatory] JOIN is not allowed if more than three tables are involved. Columns to be joined must be with absolutely similar data types. Make sure that columns to be joined are indexed.

Note: Indexing and SQL performance should be considered even if only 2 tables are joined.

3. [Mandatory] Index length must be specified when adding index on varchar columns. The index length should be set according to the distribution of data.

Note: Normally for char columns, an index with the length of 20 can distinguish more than 90% data, which is calculated by count(distinct left(column_name, index_length)) / count()*.

4. [Mandatory] LIKE '%...' or LIKE '%...%' are not allowed when searching with pagination. Search engine can be used if it is really needed.

Note: Index files have B-Tree's left most prefix matching characteristic. Index cannot be applied if left prefix value is not determined.

5. [Recommended] Make use of the index order when using ORDER BY clauses. The last columns of ORDER BY clauses should be at the end of a composite index. The reason is to avoid the file_sort issue, which affects the query performance.

Positive example: where a=? and b=? order by c; Index is: a_b_c 
Counter example: The index order will not take effect if the query condition contains a range, e.g., where a>10 order by b;Index a_b cannot be activated.

6. [Recommended] Make use of Covering Index for query to avoid additional query after searching index.

Note: If we need to check the title of Chapter 11 of a book, do we need turn to the page where Chapter 11 starts? No, because the table of contents actually includes the title, which serves as a covering index.
Positive example: Index types include primary key indexunique index and common indexCovering index pertains to a query effect. When refer to explain result, using index may appear in extra columns.

7. [Recommended] Use late join or sub-query to optimize scenarios with many pages.

Note: Instead of bypassing offset rows, MySQL retrieves totally offset+N rows, then drops off offset rows and returns N rows. It is very inefficient when offset is very big. The solution is either limiting the number of pages to be returned, or rewriting SQL statement when page number exceeds a predefined threshold.
Positive example: Firstly locate the required id range quickly, then join:
select a.* from table1 a, (select id from table1 where some_condition LIMIT 100000, 20) b where a.id=b.id;

8. [Recommended] The target of SQL performance optimization is that the result type of EXPLAIN reaches REF level, or RANGEat least, or CONSTS if possible.

Counter example: Pay attention to the type of INDEX in EXPLAIN result because it is very slow to do a full scan to the database index file, whose performance nearly equals to an all-table scan.
CONSTS: There is at most one matching row, which is read by the optimizer. It is very fast.
REF: The normal index is used.
RANGE: A given range of index are retrieved, which can be used when a key column is compared to a constant by using any of the =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, or IN() operators.

9. [Recommended] Put the most discriminative column to the left most when adding a composite index.

Positive example: For the sub-clause where a=? and b=?, if data of column a is nearly unique, adding index idx_a is enough.
Note: When equal and non-equal check both exist in query conditions, put the column in equal condition first when adding an index. For example, where a>? and b=?b should be put as the 1st column of the index, even if column a is more discriminative.

10. [For Reference] Avoid listed below misunderstandings when adding index:
  1) It is false that each query needs one index.
  2) It is false that index consumes story space and degrades updateinsert operations significantly.
  3) It is false that unique index should all be achieved from application layer by "check and insert".

SQL Rules

1. [Mandatory] Do not use COUNT(column_name) or COUNT(constant_value) in place of COUNT(*). COUNT(*) is SQL92 defined standard syntax to count the number of rows. It is not database specific and has nothing to do with NULL and non-NULL.

Note: COUNT(*) counts NULL row in, while COUNT(column_name) does not take NULL valued row into consideration.

2. [Mandatory] COUNT(distinct column) calculates number of rows with distinct values in this column, excluding NULL values. Please note that COUNT(distinct column1, column2) returns 0 if all values of one of the columns are NULL, even if the other column contains distinct non-NULL values.

3. [Mandatory] When all values of one column are NULL, COUNT(column) returns 0, while SUM(column) returns NULL, so pay attention to NullPointerException issue when using SUM().

Positive example: NPE issue could be avoided in this way:
SELECT IF(ISNULL(SUM(g)), 0, SUM(g)) FROM table;

4. [Mandatory] Use ISNULL() to check NULL values. Result will be NULL when comparing NULL with any other values.

Note: 
  1) NULL<>NULL returns NULL, rather than false.
  2) NULL=NULL returns NULL, rather than true.
  3) NULL<>1 returns NULL, rather than true.

5. [Mandatory] When coding on DB query with paging logic, it should return immediately once count is 0, to avoid executing paging query statement followed.

6. [Mandatory] Foreign key and cascade update are not allowed. All foreign key related logic should be handled in application layer.

Note: e.g. Student table has student_id as primary key, score table has student_id as foreign key. When student.student_id is updated, score.student_id update is also triggered, this is called a cascading updateForeign key and cascading update are suitable for single machine, low parallel systems, not for distributed, high parallel cluster systems. Cascading updates are strong blocked, as it may lead to a DB update storm. Foreign key affects DB insertion efficiency.

7. [Mandatory] Stored procedures are not allowed. They are difficult to debug, extend and not portable.

8. [Mandatory] When correcting data, delete and update DB records, SELECT should be done first to ensure data correctness.

9. [Recommended] IN clause should be avoided. Record set size of the IN clause should be evaluated carefully and control it within 1000, if it cannot be avoided.

10. [For Reference] For globalization needs, characters should be represented and stored with UTF-8, and be cautious of character number counting.

Note: SELECT LENGTH("轻松工作"); returns 12.
SELECT CHARACTER_LENGTH("轻松工作"); returns 4.
Use UTF8MB4 encoding to store emoji if needed, taking into account of its difference from UTF-8.

11. [For Reference] TRUNCATE is not recommended when coding, even if it is faster than DELETE and uses less system, transaction log resource. Because TRUNCATE does not have transaction nor trigger DB trigger, problems might occur.

Note: In terms of Functionality, TRUNCATE TABLE is similar to DELETE without WHERE sub-clause.

ORM Rules

1. [Mandatory] Specific column names should be specified during query, rather than using *.

Note:

  1. * increases parsing cost.
  2. It may introduce mismatch with resultMap when adding or removing query columns.

2. [Mandatory] Name of Boolean property of POJO classes cannot be prefixed with is, while DB column name should prefix with is. A mapping between properties and columns is required.

Note: Refer to rules of POJO class and DB column definition, mapping is needed in resultMap. Code generated by MyBatis Generator might need to be adjusted.

3. [Mandatory] Do not use resultClass as return parameters, even if all class property names are the same as DB columns, corresponding DO definition is needed.

Note: Mapping configuration is needed, to decouple DO definition and table columns, which in turn facilitates maintenance.

4. [Mandatory] Be cautious with parameters in xml configuration. Do not use ${} in place of #{}#param#. SQL injection may happen in this way.

5. [Mandatory] iBatis built in queryForList(String statementName, int start, int size) is not recommended.

Note: It may lead to OOM issue because its implementation is to retrieve all DB records of statementName's corresponding SQL statement, then start, size subset is applied through subList.
Positive example: Use #start##size# in sqlmap.xml.

Map<String, Object> map = new HashMap<String, Object>();  
map.put("start", start);  
map.put("size", size);  

6. [Mandatory] Do not use HashMap or HashTable as DB query result type.

7. [Mandatory] gmt_modified column should be updated with current timestamp simultaneously with DB record update.

8. [Recommended] Do not define a universal table updating interface, which accepts POJO as input parameter, and always update table set c1=value1, c2=value2, c3=value3, ... regardless of intended columns to be updated. It is better not to update unrelated columns, because it is error prone, not efficient, and increases binlog storage.

9. [For Reference] Do not overuse @Transactional. Because transaction affects QPS of DB, and relevant rollbacks may need be considered, including cache rollback, search engine rollback, message making up, statistics adjustment, etc.

10. [For Reference] compareValue of <isEqual> is a constant (normally a number) which is used to compared with property value. <isNotEmpty> means executing corresponding logic when property is not empty and not null. <isNotNull> means executing related logic when property is not null.

+ Recent posts