반응형

리액트를 공부하지 않고 감으로 시작하시는 분들은 이런 에러를 봤을 수 있고

왜 일어나는지에 대해서 의문을 품을 수 있다. 

 

내가 겪은 에러였고 왜 그런지에 대해서 알고 싶었다. 

https://ko.reactjs.org/docs/hooks-overview.html#building-your-own-hooks

 

Class에서 구현하느냐 Function에서 구현하느냐 이 차이였다.

 

내가 맞이한 에러는 아래와 같다 

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

 

 

export class SampleClass extends ... {

  const {loading, error, data} = useQuery(SampleGQL);  render(){
    return (<>      ...
    </>)
  }
}
export const SampleClass = () => {
  const {loading, error, data} = useQuery(SampleGQL);
      return <>
        ...
      </>
}

위 두 코드중에서 에러를 발생하는 코드는 어떤 것일까?

위의 문서를 잘봤다면 Class로 구현한 스타일에 문제가 있다는 것을 알 것이다. 

 

 

오류가 나지않으려면 아래 코드와 같은 Function으로 구현하여 렌더링을 해야할 것이다.

 

function으로 구현할때는 아래와 같은것들을 고려해보자.

컴포넌트가 LifeCycle API도 사용하지 않고, state도 사용하지 않고, props만 전달해주는 뷰를 렌더링한다면, 함수형 컴포넌트를 사용할 수 있다.

 

반응형

Naver Map을 설치해보자

https://github.com/react-native-seoul/react-native-kakao-login

위내용을 보며 따라간다.

  • npm은 오류납니다
    npm install react-native-nmap@0.0.66 --save
    
    전체적으로 버전을 하향해야한다.
    ...
    "dependencies: {
    	
    },
    ...
    
    위의 내용으로 설치를 진행하면 npm에서 충돌로 인해서 더이상 진행이 불가하다.

 

 

yarn install react-native-nmap@0.0.66 --save

위 명령어로 진행해야 해당 패키지가 정상적으로 설치 된다.

설치후에 ios package 를 설치해야 한다.

설치 후 에러가 발생할 수 있다.

Installing NMapsMap (3.16.0)

[!] Error installing NMapsMap
[!] /usr/bin/git clone <https://github.com/navermaps/NMapsMap.git> /var/folders/nd/lsjr321s7sxbss72ggwkq5sr0000gn/T/d20221118-42365-1i2mgxz --template= --single-branch --depth 1 --branch release/3.16.0

Cloning into '/var/folders/nd/lsjr321s7sxbss72ggwkq5sr0000gn/T/d20221118-42365-1i2mgxz'...
Note: switching to 'd34a86bee0756adf7e40636f12712315f8de975c'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c 

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

git-lfs filter-process: git-lfs: command not found
fatal: the remote end hung up unexpectedly
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'

Couldn't install Pods. Updating the Pods project and trying again...
> pod install --repo-update
Auto-linking React Native modules for target `BSpotReactNative`: RNCAsyncStorage, RNScreens, RNVectorIcons, kakao-login, react-native-nmap, react-native-safe-area-context, and react-native-splash-screen
[Codegen] Generating ./build/generated/ios/React-Codegen.podspec.json
Updating local specs repositories

CocoaPods 1.11.3 is available.
To update use: `gem install cocoapods`

For more information, see <https://blog.cocoapods.org> and the CHANGELOG for this version at <https://github.com/CocoaPods/CocoaPods/releases/tag/1.11.3>

Analyzing dependencies
[Codegen] Found FBReactNativeSpec
Downloading dependencies
Installing Alamofire (5.6.2)
Installing KakaoSDKAuth (2.11.1)
Installing KakaoSDKCommon (2.11.1)
Installing KakaoSDKUser (2.11.1)
Installing NMapsMap (3.16.0)

[!] Error installing NMapsMap
[!] /usr/bin/git clone <https://github.com/navermaps/NMapsMap.git> /var/folders/nd/lsjr321s7sxbss72ggwkq5sr0000gn/T/d20221118-42481-1bq6ix8 --template= --single-branch --depth 1 --branch release/3.16.0

Cloning into '/var/folders/nd/lsjr321s7sxbss72ggwkq5sr0000gn/T/d20221118-42481-1bq6ix8'...
Note: switching to 'd34a86bee0756adf7e40636f12712315f8de975c'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c 

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

git-lfs filter-process: git-lfs: command not found
fatal: the remote end hung up unexpectedly
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'

Couldn't install Pods. Updating the Pods project and trying again...
Command `pod install` failed.
└─ Cause: Error installing NMapsMap
[!] /usr/bin/git clone <https://github.com/navermaps/NMapsMap.git> /var/folders/nd/lsjr321s7sxbss72ggwkq5sr0000gn/T/d20221118-42481-1bq6ix8 --template= --single-branch --depth 1 --branch release/3.16.0

Cloning into '/var/folders/nd/lsjr321s7sxbss72ggwkq5sr0000gn/T/d20221118-42481-1bq6ix8'...
Note: switching to 'd34a86bee0756adf7e40636f12712315f8de975c'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c 

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

git-lfs filter-process: git-lfs: command not found
fatal: the remote end hung up unexpectedly
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'

위와 같은 에러가 발생한다면 아래 사이트를 방문하여

해당하는 명령어를 위에서부터 아래로 순차적으로 실행한다.

항상 명령어는 나한테 해당하는건지 아닌지 확인해가며 실행한다.

https://github.com/navermaps/ios-map-sdk?ref=morioh.com&utm_source=morioh.com#대용량-파일을-받기-위해-git-lfs-설치가-필요합니다

보통은 cocopods는 설치되어있으니 나는 아래와 같이 명령어를 실행했다.

 

brew install git-lfs
git-lfs install
pod install --repo-update

 

네이버 NMap 설치 

'프론트엔드 > ReactNative' 카테고리의 다른 글

[ReactNative] Class Component Error  (0) 2022.11.22
반응형

분명 잘 구현한거같은데 해당 토큰을 넣고 테스트를 진행하면

자꾸 인증이 되지 않는다는 메세지를 보게되었을때 점검해봐야하는 부분이다.

 

다른 여러가지 부분을 확인해봐야하겠지만

내 구현엔 문제가 없는데... 이런생각이라면

import한 부분을 체크해보자.

 

import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-local'; # 여기가 문제
import { ExtractJwt } from 'passport-jwt';

export class GraphqlStrategy extends PassportStrategy(Strategy, 'jwt') {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: process.env.JWT_SECRET,
      usernameField: 'email',
      passwordField: 'password',
    });
  }

  async validate(token: string) {
    return token;
  }
}

 

위에서 문제는 passport-jwt와 passport-local을 호환해서 사용했기 때문이다.

 

 

import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';

export class GraphqlStrategy extends PassportStrategy(Strategy, 'jwt') {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: process.env.JWT_SECRET,
      usernameField: 'email',
      passwordField: 'password',
    });
  }

  async validate(token: string) {
    return token;
  }
}

 

반응형

일반적으로 Pod에서 에러가나서 오류가 나는 상황을 다루진 않는다.

 

Pod는 정상인 상태인데 HPA설정을 하고 간헐적인 50x에러에 대해서 다루려고한다.

 

해당에러는 GCP에서 진행을 하였고 

Monitoring Alarm을 구성하여 간헐적인 현상을 확인하였다.

 

 

 

참고한 블로그는 사람인 기술 블로그이다. 

자세한 내용이 적혀있으니 해당내용으로 확인해보도록 하자.

https://saramin.github.io/2022-05-17-kubernetes-autoscaling/

 

Kubernetes에서 HPA를 활용한 오토스케일링(Auto Scaling)

소개 안녕하세요, 사람인HR IT연구소 채용시스템개발팀의 김용태입니다. 채용시스템개발팀은 채용 홈페이지 제작부터 채용 설계, 지원서 접수, 지원자 관리, 데이터 관리, 합격 과정에 이르기까

saramin.github.io

 

 

내가 생각했던 과정을 이러하다.

많은 양의 트래픽이 유입이 될때 Alarm로그가 발생하였고 이후 몇분 이내에 정상 상태 Alarm이 돌아왔다.

트래픽이 몰리는것과, 얼마 안되서 다시 정상으로 돌아오는 것이 Auto Scailing과정에서 문제가 있다는 생각을 했다.

 

Scale Out

확장 과정에서의 문제 발생을 확인해봐야 했다.

기본적으로 2가지 설정은 해둔상태이다.

livenessProbe:
  exec:
    command:
      - cat
      - /workspace/app/app.py
  initialDelaySeconds: 10
  periodSeconds: 10
readinessProbe:
  httpGet:
    path: /
    port: 5001
  initialDelaySeconds: 20
  periodSeconds: 30

 

livenessProbe -  서버가 살아있는 상태 확인
readinessProbe - 트래픽을 받지 않는 상태에서 쿠버네티스 내부적으로 Health체크를 진행 (트래픽 준비 상태를 체크하는 듯)

 

트래픽을 유입시키는 상태값을 설정하는데 보아하니 이 두 부분의 허용을 늦추는 상태값으로 트래픽을 늦추는 설정이 필요했다.

startupProbe - 해당 체크가 Success가 되면 livenessProbe와 readinessProbe를 체크를 허용한다.

 

spec:
    containers:
    - name: server
    	...
    	livenessProbe:
          exec:
            command:
              - cat
              - /workspace/app/app.py
          initialDelaySeconds: 10
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 5001
          initialDelaySeconds: 20
          periodSeconds: 30
        startupProbe:
          httpGet:
            path: /
            port: 5001
          initialDelaySeconds: 20
          periodSeconds: 3

 

 

Scale In

다음으로 축소 과정에서 문제발생을 확인해봐야 했다.

축소될때 무슨 이유로 트래픽이 유실되는지 생각해봐야했는데 Alarm상 생각한 이유는 한가지였다.

위 내용을 보면 matched_url_path_rule 에 UNMATCHED 라는 값이 보였다. 

트래픽이 유입되었는데 가야할 곳을 잃은거라고 생각이 들었다. 

1. Pod는 정상 종료 되었다.

2. Ingress, Service에서 트래픽이 정상적으로 처리되지 않았다.

 

이런 흐름이라면 미리 트래픽을 끊고 Pod를 유예기간을 두어서 종료시키켜야 했다.

 

terminationGracePeriodSeconds - Pod 종료 유예시간 설정

lifecycle.preStop.exec.command - 미리 멈추는 기전에 할 명령어 설정

 

spec:
	terminationGracePeriodSeconds: 60
    containers:
    - name: server
    	...
        설정들..
        ...
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sleep", "30"]

 

 

이렇게 설정하고 ab tool를 가지고 강제로 트래픽을 유입시키고 확인해보았다.

pod 숫자 증량에따라 해당 에러가 관찰 되지 않는 모습을 확인하였다. 

 

ab -n 10000 -c 100 "url"

 

반응형

schedule_interval

Airflow에서 Dag들이 실행하는데 정시에 실행이 되지않고 약간의 초가 지난뒤에 실행되는걸 볼수있다.

Run: ... 이 부분을 확인할 것

이유는

with models.DAG(
        MAIN_DAG_ID,
        default_args=default_args,
        schedule_interval='*/30 * * * * *',
        start_date=datetime(2021, 10, 12, 0, 0, 0),
        catchup=False,
        tags=["hyper-dmp", "export", "trait", "ga", "dynamic_segment"],
) as dag:
    ...

property 중 schedule_interval 값을 6자리로 유지하면 안된다.

5자리 cron expression식으로 쓸것.

그러면 원했던 시간에 실행되는 것을 볼 수 있다.

다음으로

start_date

이 속성은 현재 시간보다 앞서나가면 실행이 안된다.

예약의 조건으로 사용하거나
catchup=true속성으로 지난 시간들의 모든 schedule을 가져올때 사용하던지 해야한다.

위 코드에 없는

execution_time

해당 부분을 dag이 실행될때 부여되는 속성이다.
이상하게도 schdule_interval을 6자리 할때도 execution_time은 정확하게 부여되었다.

중요한건 해당 execution_time이 실행될때 바로 전 타임 execution_time을 확인할 수 있다는 것이다.

예를들어

현재시간 : 13:00
with models.DAG(
        MAIN_DAG_ID,
        default_args=default_args,
        schedule_interval='*/30 * * * * *',
        start_date=datetime(2021, 10, 12, 0, 0, 0),
        catchup=False,
        tags=["hyper-dmp", "export", "trait", "ga", "dynamic_segment"],
) as dag:

위 코드로 현재시간에 실행된다면 execution_time값은 무엇일까 ?

답은

12:30

이다.

누군가의 설명에 따르면 schedule_interval 간격마다 바로 전 execution_time을 실행한다

로 이해하라고 되어있었다.

반응형

gunicorn에 대해서 처음 작업해보았는데 성능을 개선해보아야했다.

worker라던지, gevent라던지 이런 부분에 대해서 알고있어야하는데

관련해서 추천할 블로그이다.

http://blog.hwahae.co.kr/all/tech/tech-tech/5567/

오늘의 집 테크 블로그인데 gunicorn에 대해서 공부하기 좋다.

나름 글이 잘읽히고 정보의 질이 좋다.

위 내용이 어느정도 읽히고 테스트를 해보았다면

오늘 에러관련내용해서 쓰는글을 이해하기 편할것이다.

문제가 되는 부분의 코드이다.

import logging.config
from gevent.monkey import patch_all
patch_all()
# 이 부분이 해결하기 위한 코드 
# import grpc.experimental.gevent as grpc_gevent
# grpc_gevent.init_gevent()

from flask import Flask
from config.default import CONFIG
from views.pixel_view import bp
from config.logger import LOGGING_CONFIG
from views.scheduler import scheduler, get_destination_template

def create_app():
    logging.config.dictConfig(LOGGING_CONFIG)
    if CONFIG['APP_ENV'] == 'PRODUCTION':
        logging.disable(logging.DEBUG)
    else:
        logging.disable(logging.NOTSET)

    ap = Flask(__name__)

    ap.url_map.strict_slashes = False
    ap.register_blueprint(bp)

    ap.config['SCHEDULER_API_ENABLED'] = True

    if not scheduler.running:
        scheduler.init_app(ap)
        scheduler.start()
        # break point
    **get_destination_template()**

    return ap

app = create_app()
logger = logging.getLogger('default')

if __name__ == '__main__':
    logger.info('APP START AND POLL START')
    app.run(port=5001)




위 코드를 보면 python cronjob도 돌리고있고 api서버의 기능도 있다.

스케줄링관련 프로세스에는 google 제품을 사용하는 코드들이 있다. bigtable요청관련된 부분이다.

그렇지만 위에 break point를 걸어보면 아래와 같은 코드에서 freezing이 걸린다.

def _run_channel_spin_thread(state):

    def channel_spin():
        while True:
            #freezing point 
            cygrpc.block_if_fork_in_progress(state)
            event = state.channel.next_call_event()
            if event.completion_type == cygrpc.CompletionType.queue_timeout:
                continue
            call_completed = event.tag(event)
            if call_completed:
                with state.lock:
                    state.managed_calls -= 1
                    if state.managed_calls == 0:
                        return

    channel_spin_thread = cygrpc.ForkManagedThread(target=channel_spin)
    channel_spin_thread.setDaemon(True)
    channel_spin_thread.start()




이 파일의 경로는 아래와 같다





grcp에서 프로세스를 fork하는 부분에서 freezing이 걸리는걸 확인하는 순간이다.

충돌이 일어난다고 볼수 있다.

이 부분을 해결하기 위해선 첫 코드에서 주석을 해제하는 코드를 작성해야한다.

import logging.config
from gevent.monkey import patch_all
patch_all()

# 이 부분이 해결하기 위한 코드 
import grpc.experimental.gevent as grpc_gevent
grpc_gevent.init_gevent()

from flask import Flask
from config.default import CONFIG
from views.pixel_view import bp
from config.logger import LOGGING_CONFIG
from views.scheduler import scheduler, get_destination_template

def create_app():
    logging.config.dictConfig(LOGGING_CONFIG)
    if CONFIG['APP_ENV'] == 'PRODUCTION':
        logging.disable(logging.DEBUG)
    else:
        logging.disable(logging.NOTSET)

    ap = Flask(__name__)

    ap.url_map.strict_slashes = False
    ap.register_blueprint(bp)

    ap.config['SCHEDULER_API_ENABLED'] = True

    if not scheduler.running:
        scheduler.init_app(ap)
        scheduler.start()
        # break point
    **get_destination_template()**

    return ap

app = create_app()
logger = logging.getLogger('default')

if __name__ == '__main__':
    logger.info('APP START AND POLL START')
    app.run(port=5001)




사용한 패키지 버전이다.

gevent = "~=21.8.0"
gunicorn = "~=20.1.0"

google제품과 사용 시 freezing현상이 있다면 이 부분을 확인해보면 도움이 될 거 같다.

'백엔드 > Python' 카테고리의 다른 글

[Python]ModuleNotFoundError: No module named '_ctypes'  (0) 2021.01.04
반응형

실패상황1

1Airflow에서 mysql_default를 사용중에 localhost:3306을 설정하여 커넥션을 시도하였으나
실패하였다.

실패상황2

docker inspect containerId 를 통해서 내부 ip를 파악해여 커넥션을 시도하였으나
실패하였다.

이유가 무엇일까 생각해보니 네트워크가 서로 분리되어있었다.

mysql은 기본 네트워크 (bridge)에 존재하였고

airflow는 생성할때 입력한 네트워크에 container들과 함께 생성되었다.

# 네트워크 리스트 명령어
docker network ls

# 해당 네트워크에 어떤 컨테이너가 있는지, 또는 정보를 확인하는 명령어
docker network inspect networkName

# docker network inspect bridge 
# docker network inspect "airflow network name"

서로 다른 네트워크에 존하는것을 확인하였다. 그렇다면 어떻게 해야할까 ?



내가 작업한 방법은 airflow network에 mysql container를 붙여서 내부 아이피를 사용하는 방법을 사용하였다.

먼저 local-mysql container를 bridge 네트워크에서 제거하는 명령어

docker network disconnect bridge local-mysql




이후 airflow network에 local-mysql을 붙이는 명령어

docker network connect "airflow network name" local-mysql




이후 잘되었는지 확인

docker network inspect "airflow network name"
# docker network inspect hyper-dmp-v2-workflow_default 결과

[
    {
        "Name": "hyper-dmp-v2-workflow_default",
        "Id": "97e809b8c591b205ab25ac0ac0c30efcbea1628cf0dbafb977a5ff00af551906",
        "Created": "2021-08-17T06:18:29.488748Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "290d92d8050eabee9e160f3e0439df8fb5d4d4d622a8f14317f68966c68d9947": {
                "Name": "workflow_airflow-worker_1",
                "EndpointID": "f28016d500d349b9dcc123db5f4312bca8226b6ebb3d4552f571b732b7e6be65",
                "MacAddress": "02:42:ac:12:00:05",
                "IPv4Address": "172.18.0.5/16",
                "IPv6Address": ""
            },
            "3ea2b515e45b2bd3d17b4e5b34f8ddb3ad5eb5d773c55a71724d7dfa7eb9a8c8": {
                "Name": "workflow_airflow-webserver_1",
                "EndpointID": "3e38cb185a20ba33157d363574b2fd6844c3834ebe633713321dbcd7ece26a4d",
                "MacAddress": "02:42:ac:12:00:07",
                "IPv4Address": "172.18.0.7/16",
                "IPv6Address": ""
            },
            "5a2cebcd308971a2db78a321ba99f304004111fcdffab2648f2264d8e156a359": {
                "Name": "workflow_airflow-scheduler_1",
                "EndpointID": "2cd982cea25db9651d98a503d9009e1ed20d68c09c513ca9c5894708d06b58ee",
                "MacAddress": "02:42:ac:12:00:04",
                "IPv4Address": "172.18.0.4/16",
                "IPv6Address": ""
            },
            **"8e68ca23d180eca523b5c1bc35d44c11c5ffab95b7734724279582313df5d0c9": {
                "Name": "local-mysql",
                "EndpointID": "e9dd16cdf8fdd1856cea04ee2ba74948928bd796b681f8182c81ac6ed1711f6e",
                "MacAddress": "02:42:ac:12:00:06",
                "IPv4Address": "172.18.0.6/16",
                "IPv6Address": ""
            },# 이 부분이 추가 된 부분**
            "b3788433fb68182e847b8d782e38cd07caffdf4f7de41bba59a8705d1cd00cc9": {
                "Name": "workflow_redis_1",
                "EndpointID": "6ed71a24bf27c327ed996fbaae0ade72bee75c4e371b80d11aefff8167aadef7",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "c3a4444096dd17a2d43449fc5c0273c786ba9c14cd328ef3818bc6724cd985d0": {
                "Name": "workflow_flower_1",
                "EndpointID": "27d9564194beebf24cced1e5802e5e49b2d55e2bc89cea6f4ef95d26481f2d6f",
                "MacAddress": "02:42:ac:12:00:08",
                "IPv4Address": "172.18.0.8/16",
                "IPv6Address": ""
            },
            "ce08580c8b40b50798a37ab39072e22f3bc9c37cae1fc9adb328ec5cc0b1ac53": {
                "Name": "hworkflow_postgres_1",
                "EndpointID": "d7640e67ec833bb595c4af43ce374d80eeaf049a70af8e0c9afc68c098e6a40f",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "workflow",
            "com.docker.compose.version": "1.29.1"
        }
    }
]

A네트워크에 Container를 붙여서 내부아이피를 사용하게 만드는 법이다.

보통 로컬 컴퓨터에 DB를 깔고 docker로 다른 제품을 사용하다보면 이렇게 네트워크까지 가지고있는 docker compoer파일들이 있는데
이런것들을 사용하던 로컬 DB와 혼용할때 유용하다.

반응형

젠킨스를 사용하다보면 상단의 업데이트가 표기된것을 볼 수 있다.

빨간 숫자 2

해당 표기를 눌러보면 Plugins, Jenkins 업데이트하라는 내용이 대부분이다.

젠킨스를 업데이트하여 최신의 기능을 빠르게 적용시켜보자.

젠킨스 경로

# 젠킨스 경로 이동
cd /usr/lib/jenkins

# jenkins.war 파일 확인
ls -al

# 최종 경로 
# /usr/lib/jenkins/jenkins.war

기존 jenkins file 백업

#기존의 jenkins.war는 백업
cp jenkins.war jenkins_20200529.war

{

젠킨스 업데이트 파일 다운로드

wget http://mirrors.jenkins-ci.org/war/latest/jenkins.war

또는

자신이 운영하는 젠킨스 사이트에서 업데이트 하라는 링크를 직접 입력한다. (버전이 명시적임)

wget $LINK

}

젠킨스 재시작

service jenkins restart
  • 젠킨스 파일 찾기
find / -name 'jenkins.war'
반응형

가끔 프로젝트를 생성하다보면 내가 원하지 않은 파일이 올라가있을때가 있다.

올라간것을 지우려면 직접 Github repository에 가서 변경하거나 귀찮게 작업을 해왔었다.

로컬에서 작업을 진행 후 push를 해서 반영가능하게 하는 작업을 아래와 같이 설명 한다.

아래는 bin폴더가 잘못 올라간 상황을 가정한다.

  1. git ignore 파일에 아래와 같이 추가, 작성한다.
bin/
  1. 아래와 같은 명령어를 실행한다.
git rm -r --cached bin

3. push 한다. 

git push 리모트-저장소이름 로컬-브렌치명


4. 리모트 저장소를 확인해보면 없어진것을 확인할 수 있다.

'Utils > Github' 카테고리의 다른 글

[Github] Projects 메뉴 활용  (0) 2021.01.10
[GitHub] 프로젝트 삭제 방법 - 웹  (0) 2016.09.15
반응형

서비스 운영 중 다음과 같은 에러가 발생되었다.

AWS CloudWatch Error Log:

2020-04-16 12:38:00.373 ERROR 1 --- [pool-1-thread-1] o.s.s.s.TaskUtils$LoggingErrorHandler : Unexpected error occurred in scheduled task
org.springframework.dao.DeadlockLoserDataAccessException: PreparedStatementCallback; SQL [DELETE FROM SPRING_SESSION WHERE EXPIRY_TIME < ?]; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:267) ~[spring-jdbc-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) ~[spring-jdbc-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1443) ~[spring-jdbc-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633) ~[spring-jdbc-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:862) ~[spring-jdbc-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:917) ~[spring-jdbc-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:927) ~[spring-jdbc-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.lambda$cleanUpExpiredSessions$8(JdbcIndexedSessionRepository.java:553) ~[spring-session-jdbc-2.2.0.RELEASE.jar!/:2.2.0.RELEASE]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.cleanUpExpiredSessions(JdbcIndexedSessionRepository.java:553) ~[spring-session-jdbc-2.2.0.RELEASE.jar!/:2.2.0.RELEASE]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93) [spring-context-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_151]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_151]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_151]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_151]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_151]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_151]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_151]
Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:123) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1347) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-3.4.2.jar!/:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-3.4.2.jar!/:na]
at org.springframework.jdbc.core.JdbcTemplate.lambda$update$0(JdbcTemplate.java:867) ~[spring-jdbc-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617) ~[spring-jdbc-5.2.3.RELEASE.jar!/:5.2.3.RELEASE]

Mysql 에서 자신의 Transaction Isolation Level을 확인하려면 다음과 같은 명령어를 사용한다

show variables like 'tx_isolation';

위의 에러는 REPEATABLE READ 라는 상태일 때 나타나게 된다.

참고 문서에 아래와 같이 나와있다.

REPEATABLE-READ에서는 현재 Select 버전을 보장하기 위해 Snapshot을 이용하는데, 
이 경우 해당 데이터에 관해서 암묵적으로 Lock과 비슷한 효과가 나타납니다.

즉, Select 작업이 종료될 때까지 해당 데이터 변경 작업이 불가합니다.

tx_isolation 변수의 상태는 4가지가 있다.

  • READ UNCOMMITTED
    다른 트랜잭션이 Commit 전 상태를 볼 수 있음Binary Log가 자동으로 Row Based로 기록됨 (Statement설정 불가, Mixed 설정 시 자동 변환)
  • READ-COMMITTED
    Commit된 내역을 읽을 수 있는 상태로, 트랜잭션이 다르더라도 특정 타 트랜잭션이 Commit을 수행하면 해당 데이터를 Read할 수 있음Binary Log가 자동으로 Row Based로 기록됨 (Statement설정 불가, Mixed 설정 시 자동 변환)
  • REPEATABLE READ
    MySQL InnoDB 스토리지 엔진의 Default Isolation LevelSelect 시 현재 데이터 버전의 Snapshot을 만들고, 그 Snapshot으로부터 데이터를 조회동일 트랜잭션 내에서 데이터 일관성을 보장하고 데이터를 다시 읽기 위해서는 트랜잭션을 다시 시작해야 함
  • SERIALIZABLE
    가장 높은 Isolation Level로 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸림다른 트랜잭션에서는 해당 영역에 관한 데이터 변경 뿐만 아니라 입력도 불가

Oracle 에서는 READ-COMMITTED 상태가 Default 상태여서 해당 에러가 나타나지 않는다.

Mysql 의 tx_isolation변수값을 READ-COMMITTED 값으로 변경해야지 해당 에러가 발생하지 않는다.

참고 :

  1. https://gywn.net/2012/05/mysql-transaction-isolation-level/

'DataBase' 카테고리의 다른 글

[Mysql] Mysql 계정 설정  (0) 2021.01.23

+ Recent posts