기본 콘텐츠로 건너뛰기

Concurrency in Go 책 읽고 대략 요약

원본은 https://laced-river-472.notion.site/Concurrency-in-Go-7f97812aee104adc8cc6d60591f01316 에 요약 해놓음.

2024년 3월 27일 ~ 2024년 3월 29일

Concurrency in go 책 검토

https://github.com/SK-Jin/concurrency-in-go-src

  1. 1장 동시성 소개

    1. 동시성이 어려운 이유
  2. 2장 코드 모델링: 순차적 프로세스간의 통신(CSP)

    1. 동시성과 병렬성의 차이
    2. 동시성을 지원하는 언어의 장점
    3. Go의 동시성의 철학
  3. 3장 동시성 구성요소

    1. goroutine
    2. Sync Package
    3. Channels
    4. select-statement
    5. defer-statment
  4. 4장 동시성 패턴

    1. 제한(Confinement)
      1. Ad-hoc
        1. 내부적인 규칙, 암묵적인 규칙 등 시간적인 문제로 깨트려지는 경우가 있을 수 있음.
      2. lexical
        1. 도구에서 문제 상황에 대해 통보, 이를 개선 하는 형태로 접근
      3. 동기화를 사용할 수 있다면, 제한을 추구해야 함.
        1. 성능을 향상시키고, 개발자의 인지 부하를 줄이기 위함
        2. 동기화에는 비용이 들며, 이를 피할 수 있으면, 임계 염역이 없기 때문에 동기화 비용을 지불할 필요가 없음.
        3. 동기화로 인해 발생 가능한 모든 문제도 막을 수 있음
    2. for-select 루프
      1. 채널에서 반복 변수 보내기
      2. 멈추기를 기다리면서 무한히 대기
    3. 고루틴 누수 방지
      1. 고루틴 작지만 리소스를 필요로 함.
      2. 가비지 콜렉터에 의해 수집 되지 않음. -> 원인은 제각각 이겠지만, 여전히 활성화 되어 있을 것이므로
      3. 고루틴 종료 조건
          • 작업 완료
          • 복구할 수 없는 에러로 인해 더 이상 작업을 계속할 수 없을 때
          • 작업을 중단하라는 요청을 받았을 떄 -> 네트워크 효과(연관된 고루틴 존제)가 있으므로 제일 중요
      4. 접근 1
        1. Cancel chan 생성 하여 기존 for~range 구조에셔 for~select 구조 변경 cancel 요청 감시 하도록 수정
      5. 접근 2
        1. Cancel chan 생성, 기존 for 구조에서 for~select 구조 변경 cancel 요청 감시 하도록 수정
    4. or-channel
        • 때로는 하나 이상의 done 채널을 하나의 done 채널로 결합해, 그 중 하나의 채널이 닫힐때 결합된 채널이 닫히도록 해야할 수 있음.
        • select 로 처리하면 좋으나, 때때로 런타임 작업 중인 done 채널 갯수를 알지 못하는 경우가 있음
      1. 재귀 및 고루틴들을 통해 복합done 채널 생성
    5. 에러처리
      1. error path 에 주의?
      2. 에러 처리의 책임자는 누구인가?
        1. 호출한 함수에게 오류 상황을 반환하여 알린다.
          1. type Result struct { // <1> Error error Response *http.Response } checkStatus := func(done <-chan interface{}, urls ...string) <-chan Result { // <2>
    6. 파이프라인
        • 긴 하나의 함수? 대신에 파이프라인 처리가 향후 관리에서도 효율적
        • 어떤 시스템을 변경하고, 하나의 논리적인 변화를 위해 여러 영역을 변경하였다면, 잘못된 추상화 가능성 있음.
        • 시스템에서 추상화를 구성하는 데 사용할 수 있는 또 다른 도구
        1. 특히, 프로그램이 스트림이나 데이터에 대한 일괄 처리 작업들을 처리해야 할 때 매우 강력한 도구
          • 파이프라인의 각각의 단계를 스테이지(Stage) 라고 함.
          • 하나의 단계를 데이터를 가져와서 변환을 수행하고, 데이터를 다시 전송하는 것.
          • 파이프 라인 중 팬 인, 팬 아웃 가능, 속도를 제한 하는 것도 가능.
          • 함수형 프로그램 과 연관, 모나드 가 생각 날 수 있음.
          • 단계를 수정하지 않고, 높은 수준에 수정으로 원하는 바를 얻을 수 있음.
          • pipeline []int 입력, multiply, add 형태로 구현, 출력이 chan int 형태가 되도록 generator, multiply, Add 구현 하여 호출
          • 기존 예제와 차이점
          1. = 입력 및 출력이 동시에 실행되는 컨텍스트에서 안전하기 때문에 각 단계에서 안전하게 동시에 실행 가능
          2. = 파이프 라인의 각 단계가 동시에 실행된다는 점. 즉 모든 단계가 입력만을 기다리며, 출력을 보낼수 있어야 함.
          3. = 이로 인해 각 단계들로 하여금 특정 타임 슬라이스에서 상호 돌립적으로 실행 될 수 있도록 허용한다는 점.
            • 기존 함수형 호출은 모든 단계가 완료되어야 처음부터 입력이 가능하지만, 파이프라인은 출력이 비워지는 순간 입력이 채워지게 되므로 사실상 여러 단계가 동시에 동작하는 효과가 있음.
          • 파이프라인 생성기
          1. 이산 값의 집합을 채널의 값 스트림으로 변환하는 함수
              • 유용한 생성기들
              1. repeat 주어진 값들을 순차적으로 반복
              2. 함수에서 주어진 값들을 반복
    7. Pan-out, Pan-in
        • 파이프라인의 특정 단계에서 시간이 많이 걸리는 경우, 다른 단계에 영향을 미침.
        • 파이프라인의 흥미로운 점, 개별 단계를 조합해 데이터 스트림에서 연산 할 수 있고, 파이프라인을 여러번 재사용 가능.
        • 여러개의 고루틴을 통해, 파이프라인의 상류 단계로 부터 데이터를 가져오는 것을 병렬화하면서 파이프라인 한단계를 재사용 가능
        • 팬 아웃 : 파이프라인의 입력을 처리하기 위해 여러 개의 고루틴 들로 시작하는 프로세스
        • 팬 인 : 여러 결과를 하나의 채널로 결합하는 프로세스
        1. = 여러 소비자가 읽어 들이는 하나의 다중화된 채널을 생성하는 것,
        2. = 하나의 입력 채널마다 고루틴을 동작 시키는 것
        3. = 입력 채널이 모두 닫혔을때 다중화된 채널을 닫는 하나의 고루틴과 관련돼 있음.
        4. = 결과가 도착하는 순서가 중요하지 않은 경우 사용.
        • 팬인, 팬아웃 적용 가능한 곳
        1. = 단계가 이전에 계산한 값에 의존하지 않는다. 즉 순서 독립성을 가진다.
        2. = 단계를 실행하는데 시간이 오래 걸린다.
    8. 8.or-done 채널
      1. Or 채널에 Done 채널 처리가 추가된 형태, Done 입력시 연관 채널 종료 처리
    9. 9.tee 채널
      1. 입력 하나에 대해 2개의 출력을 처리 하는 채널,
    10. 10.bridge 채널
      1. genval 에서 채널집합(채널당 값 이 들어간 채널)을 하나씩 넣고 닫는다.
      2. bridge 패턴에서는 각각 전달 받은 채널을 받아서 하나의 입력으로 처리해 준다.
        1. chanStream <-chan <-chan interface{}, intChanStream := make(chan (<-chan interface{})) // <2>
    11. 대기열 사용(queuing)
        • 파이프라인이 아직 준비 되지 않았더라도, 파이프라인에 작업을 받아들이는 것이 유용할 때가 있다.
        • 대기열을 널리 사용하지 않는 이유.
        1. = 프로그램 최적화 마지막 단계에 적용함.
        2. = 대기열을 성급하게 도입하면 데드락이나 라이브락 과 같은 동기화 문제가 드라나지 않을 수 있음
        3. = 프로그램이 정확해짐에 따라 대기열이 얼마나 필요한지 알게 될 수 있음.
        • 대기열이 프로그램의 총 실행 속도를 높여주지는 않음.
        1. = 단지, 프로그램이 다른 방식으로 동작하도록 도와줌.
        2. = 대신에 좀 더 CPU 유휴시간을 활용할 수 있게 도와줌.
        • 대기열 사용이 시스템의 전반적인 성능을 향상시킬 수 있는 상황.
        1. = 특정 단계에서 일괄 처리 요청이 시간을 절약하는 경우
        2. = 특정 단계의 지연으로 인해 시스템에 피드백 루프가 생성되는 경우
        • 파일 쓰기시 정킹 단위로 한번에 수행 처리, IO 처리 속도 개선 효과
        • 상위단계의 지연이 파이프라인 전체에 영향을 미침,
        1. = 보통 상위단계에서 단계별로 영향을 발생, 파악이 어려울수 있음.
        • 파이프 라인의 효율성이 특정 임꼐 값 아래로 떨어지면 파이프 라인 상류 단계의 시스템이
        1. = 파이프라인으로의 입력을 늘리기 시작하고, 파이프라인 효율의 저하로 이어짐... 죽음의 나선 시작
        2. = 실패에 대한 안전장치(fail-safe) 가 없으면 파이프라인을 이용하는 시스템은 결코 회복 되지 않음.
        • 시간 초과 처리는 필수, 죽은 요청 처리하다가 피드백 루프를 생성해 파이프 라인의 효율을 떨어뜨림.
        • 대기열의 상황은 몇몇 상황에서만 파이프라인의 실행시간을 단축시킴.
        • 여기저기 파이프라인 도입시 오히려 늦어질 수 있음.
        • 리틀의법칙(little's law) : 대기열 사용 이론에서 충분한 샘플링을 통한 파이프라인의 처리량을 예측하는 법칙
        1. = 진입 속도와 탈출 속도가 같은 경우에만 도입해야 함.
    12. Context 패키지
        • 고루틴 취소를 위한 Done 처리는 잘 동작하지만, 단순하면서 제한 적이다.
        • 취소되었다는 알림 대신, 취소 이유가 무엇인지, 또는 함수가 마감 시한이 있는지 추가적인 정보가 있다면 도움이 됨.
        • 시스템 크기에 상관없이 일반적으로 이들 정보를 Done 채널로 감쌀 필요가 있다는 것이 확실함.
        • 그래서, Done 을 표준 패턴화 하고 패키지 한 것이 context 패키지.
        • 두가지 주요 목적
        1. = 호출 그래프상의 분기를 취소하기 위한 AIP 제공
        2. = 호츨 그래프를 따라 요청 범위request-scope 데이터를 전송하기 위한 데이터 저장소(data-bag) 제공
        • 함수의 취소 한다는 것의 의미 -> context 패키지에서 관리 가능함.
        1. = 고루틴의 부모가 해당 고루틴을 취소하고자 할 수 있다.
        2. = 고루틴이 자신의 자식을 취소하고자 할 수 있다.
        3. = 고루틴 내의 모든 대기 중인 작업은 취소 될 수 있도록 선점 가능할 필요가 있다.
        • Context 에 타입을 다르게 선언하면 값은 같아도 추가 할 수 있다.
    type foo int
    type bar int
    func main() {
    		m := make(map[interface{}]int)
    		m[foo(1)] = 1
    		m[bar(1)] = 2
    
    		fmt.Printf("%v", m)	//map[1:2 1:1]
    }
    
    //- Context 의 인스턴스에 값을 저장해야 함.
    type ctxKey int
    
    const (
    	ctxUserID ctxKey = iota
    	ctxAuthToken
    )
    
    func UserID(c context.Context) string {
    	return c.Value(ctxUserID).(string)
    }
    
    func AuthToken(c context.Context) string {
    	return c.Value(ctxAuthToken).(string)
    }
    
    func ProcessRequest(userID, authToken string) {
    	ctx := context.WithValue(context.Background(), ctxUserID, userID)
    	ctx = context.WithValue(ctx, ctxAuthToken, authToken)
    	HandleResponse(ctx)
    }
    
    
  5. 5장 확장에서의 동시성

    1. 에러전파

        • 분산 등의 처리 쉽게 오류가 발생할 수 있음. 하지만 문제의 원인을 파악하기 쉽지 않음.
        • 크고 복잡한 시스템에서 오류를 어떻게 전달해야 할까?
        • 오류 처리를 자신의 것으로 하는 방안이 필요.
        • 에러에서 취해야 하는 정보
        1. = 발생한 사전
            • 디스크가 찼다,
            • 소켓이 닫혔다.
            • 자격이 만료되었다.
        2. = 발생한 장소 와 시점
            • 호출이 시작된 메서드 부터, 에러가 발생한 위치가 있는 전체 스택 트레이스 포함.
            • 실행중인 콘텍스트 관련 정보 포함
            • 분산 시스템인 경우에는 발생한 시스템 정보 표시 해야 함.
            • 에러 시간은 UTC 기준 시간으로 표시
        3. = 사용자 친화적인 메세지
            • 시스템 및 시스템의 사용자에 맞춰 조정해야 함
            • 친화적인 메세지는 인간 중심적이며 문제가 일시적인지 여부를 포함해야 함.
        4. = 사용자가 추가적인 정보를 얻는 방법
            • 어떤 시점에 누군가는 에러가 발생했을때 일어난 일을 자세히 알고 싶어 할 것
            • 사용자에게 표시되는 에러는 에러가 기록된 시간이 아닌 발생한 시간.
            • 에러가 생성 됐을때의 전체 스택 트레이스 등 에러의 전체 정보를 표시하는 로그에 상호 참조할수 있는 방법(또는 ID) 제공 해야 함.
            • 버그 추적 시스템에서 비슷한 문제를 집계하는 데 도움이 되는 스택 트레이스의 해시 값을 포함하는 방식도 유용.
        5. = 아무런 정보 없이 오류만 노출 되는 것은 실수 이며 버그. 에러에 대해 생각할 수 있는 범용적인 프레임워크 필요.
            • 모든 에러는 2가지로 나뉨.
            1. ++ 버그 - 사용자가 시스템에 맞춰 정의하지 않은 에러 또는 "처리되지 않은" 에러
            2. ++ 알려진 예외적인 경우(네트워크 단전, 디스크 쓰기 실패)
            • 모든 오류를 다 감싸서 호출한 곳으로 전달할 필요는 없음.
            1. ++ 자기 모듈 혹은 코드에 유용한 콘텍스트를 추가할 수 있는 경우에만 에러를 감싸서 전달.
            2. ++ 나저지는 처리 하지 않음. 처음 발생한 곳에서 이미 오류 처리를 하고 있을 것이므로
    2. 2.시간 초과 및 취소

        • 동시성 코드로 작업할 떄, 시간 초과(timeout) 이나 취소(cancellation)가 자주 발생함.
        • 시간 초과는 동작을 이해할 수 잇는 시스템을 만드는 여러 요소 가운데 결정적인 요소
        • 취소는 시간 초과에 따르는 자연스러운 반응.
        • 동시 프로세스가 시간 초과를 지원하기를 원하는 이유
        1. = 시스템 포화
            • 시스템 경계에 잇는 요청이 오랜 시간 후에 처리되는 것 보다는 시간 초과 되는 것을 원할 수 있음.
            1. ++ 시간 촉화 되었다고 해도 요청이 반복될 가능서잉 낮음
            2. ++ 메모리 내 요청을 저장하기 위한 메모리, 영속적인 대기열을 저장하기 위한 디스크 공간등 요청을 저장할 수 있는 리소스가 부족함.
            3. ++ 시간이 지날수록 요청 또는 전송 중인 데이터의 필요성이 줄어듬.
        2. = 오래된 데이터
            • 어떤 데이터는 적절한 데이터가 있을 수 있음.
            • 데이터가 만료되기 전에 처리 해야 함.
            • context.WithDeadline, context.WithTimeout, context.Cancel 등을 이용
        3. = 데드락을 막으려는 시도
            • 모든 동시 작업에 시간 초과를 설정하는 것은 불합리 하다.
            • 시간 초과 기간을 설정하는 목적은 데드락을 막기 위한 것, 적당한 사간 내에 차단 해제될 만큼만 짧으면 됨.
            • 데드락을 파하기 위해 시간 초과를 설정하려는 시도는 잠재적으로 시스템에서 데드락을 유발하는 문제를 라이브락을 유발하는 문제로 바꿀 수 있음.
            1. ++ 대형 시스템은 구성품이 훨씬 많으므로 재부팅을 통한 시스템 복구를 통한 데드락 보단, 시간이 허락되면 복구가 가능한 라이브락이 나음.
        • 동시 프로세스가 취소 되는 이유
        1. = 시간 초과 - 암묵적인 취소
        2. = 사용자 개입
        3. = 부모 프로세스의 취소
        4. = 복제된 요청 - 여러곳에 동시 요청 빠른 응답 온곳 빼고 나머지는 취소..
    3. 3.하트비트

        • 2가지 유형의 하트비트(HeartBit)
        1. = 일정 시간 간격으로 발생하는 하트비트
        2. = 작업 단위 시작 부분에서 발생하는 하트비트
        • 데드락 또는 무한 또한 장시간 대기 같은 장애 시에 짧은 시간내에 원인 파악 가능
    4. 4.복제된 요청

        • 일부 어픞리케이션의 경우, 가능한 빨리 응답을 받는 것이 최우선 과제.
        • 성능상의 이점을 위해 일종의 교환을 할수 있음.
        1. = 여러 핸들러에게 요청을 복제할수 있고, 그중 하나는 다른 핸들러보다 빠르게 리턴 될 것.
        2. = 리소스를 소모를 해서 여러개를 돌리는 단점이 있으나, 빨리 응답 온것중 하나를 답하고, 나머지는 취소
        3. = 응답 속도가 비슷한 경우 리소스 소모하여 요청하는 것이 의미 없으므로 적용하면 안됨.
        4. = 설치, 유지보수 등의 비용이 비싸지만, 속도가 목적인 경우 사용.
    5. 5.속도 제한

        • 속도 제한이란?
        1. = 리소스에 대한 접근을 단위 시간당 특정 횟수로 제한 하는 것.
        2. = 여기서 리소스는 API 연결, 디스크 읽기/쓰기, 네트워크 패킷, 에러 등
        • 속도 제한을 적용하는 이유
        1. = 시스템이 사전에 정한 속도 경계 이상 벗어나지 않게 하므로 시스템의 성능, 안정성을 확보하고자 하는 것
        2. = 시스템 속도 제한을 도입하여 시스템의 전체 벡터 공격에 대한 차단을 하는 것.
        3. = 리소스가 허용하는 한 빠르게 시스템에 접근 할 수 있으면 악의적인 사용자는 모든 종류의 작업을 할 수 있음.
        4. = 시스템에 대한 요청의 속도를 제한하지 않으면, 쉽게 보안을 설정할 수 없음.
        5. = 악의적인 사용이 속도 제한의 유일한 이유는 아님.
            • 분산 시스템에서 합법적인 사용자가 너무 많은 양의 작업을 수행하거나,
            • 버그가 있는 코드를 수행하므로 인해 다른 사용자의 시스템 성능을 저하시킬수 있다.
        • 증상
        1. = 분산 데이터베이스에서 쿠럼(Quorum:완료되었다고 여겨지는 작업에 반드시 응답해야 하느 서버의 수)을 잃어 버리고, 쓰기를 허용하지 않게 돼, 기존 요청이 실패하게 되며, 결국 뭔가 잘못된 일이 일어날 수 있음을 알 수 있음.
        2. = 결국 시스템이 스스로에게 Ddos 같은 공격을 수행하게 됨.
        • Go 에서 속도 제한 알고리즘
        1. = 토큰버켓(Token Bucket)

            • 리소스를 이용하려면, 접근 토콘이 있어야 하며, 접근 토큰이 없는 경우, 사용이 제한된다.
            • 토큰의 깊이는 d 이며, 한번에 d 개까지 토큰은 사용가능하다.
            • 토큰이 사용가능할 때까지 대기열에서 기다리던가, 요청을 거부 한다.
          1. 참고 코드
          import "[golang.org/x/time/rate](<http://golang.org/x/time/rate>)"
          func Open() *APIConnection {
          	return &APIConnection{
          		apiLimit: MultiLimiter(
          			rate.NewLimiter(Per(2, time.Second), 2),
          			rate.NewLimiter(Per(10, time.Minute), 10),
          		),
          		diskLimit: MultiLimiter(
          			rate.NewLimiter(rate.Limit(1), 1),
          		),
          		networkLimit: MultiLimiter(
          			rate.NewLimiter(Per(3, time.Second), 3),
          		),
          	}
          }
          
          1. 참고 코드2
          type APIConnection struct {
          	networkLimit,
          	diskLimit,
          	apiLimit RateLimiter
          }
          func (a *APIConnection) ReadFile(ctx context.Context) error {
          	if err := MultiLimiter(a.apiLimit, a.diskLimit).Wait(ctx); err != nil {
          		return err
          	}
          	// Pretend we do work here
          	return nil
          }
          
          func (a *APIConnection) ResolveAddress(ctx context.Context) error {
          	if err := MultiLimiter(a.apiLimit, a.networkLimit).Wait(ctx); err != nil {
          		return err
          	}
          	// Pretend we do work here
          	return nil
          }
          
          
    6. 6.비정상 고루틴의 치료

        • 데몬과 같이 수명이 긴 프로세스에서는 수명이 긴 고루틴의 집합을 사용하는 것이 일반적
        • 요점은 고루틴이 외부의 도움없이 복구 할수 없는 나쁜 상태에 빠지기 쉽다는 점.
        • 장시간 사용하는 고루틴이 건강한 상태인지 확인하고, 건강한 상태가 아니면, 재시작하도록 하는 것이 도움이 됨.
        • 고루틴을 관리하는 스튜어트(steward: 관리인)
        • 모니터링 되는 고루틴을 와드(ward: 피후견인)
        • 스튜어트는 와드의 고루틴이 비정상적인 상태가 되면 해당 고루틴을 재시작하도록 한다.
        • 이를 위해 해당 고류틴을 재시작할 수 함수의 참조가 필요함.
  6. 6장 고루틴과 Go 런타임

댓글

이 블로그의 인기 게시물

이클립스 실행 오류와 eclipse.ini 수정

1. 실행시 Java was started but returned exit code=13 에러가 날때 --> Win7 64bit를 사용중인데, 이 오류가 발생하고 있었습니다. 제가 자바도 이클립스용도 32비트 버젼을 사용중이었는데, 자바만 64비트용으로 설치를 했더니, 생긴 문제였습니다. 이클립스 64비트를 설치하시면 해결됩니다. 2.이클립스 폴더내 eclipse.ini 기본값(보통 아래 처럼 되어 있습니다.) -startup plugins/org.eclipse.equinox.launcher_1.1.0.v20100507.jar --launcher.library plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.1.R36x_v20100810 -product org.eclipse.epp.package.jee.product --launcher.defaultAction openFile --launcher.XXMaxPermSize 256M -showsplash org.eclipse.platform --launcher.XXMaxPermSize 256m --launcher.defaultAction openFile -vmargs -Dosgi.requiredJavaVersion=1.5 -Xms40m -Xmx512m 3.실행하자 마자 javaw.exe 찾기 실패시  --> jdk가 설치된 경로(javaw.exe가 있는 경로)를 추가해준다. 맨 아래쪽에 삽입하니 안되더군요.(왜죠?) -vmargs 윗부분에 삽입했습니다. 다른 블로그님 들 글에선 open 위쪽에 쓰니 괜찮다는 글도 있으니 참고하세요. -vm c:\Program Files\java\jre6\bin\javaw.exe 4.이클립스 속도 향상을 위한 추가값 출처:  http://blog.naver.com/sungback/90097516641 검색도중 이클립스 속도 향상 정보를 발

[c#.net] WPF 사용 중 xaml관련 실행시 오류 와 대처 방법

wpf 사용 중 xaml관련 실행시 오류 가 발생해서 자그마치 2일을 소비 했다..--;; 오류 내용은 아래와 같다. ================================== 'System.Windows.Markup.XamlParseException' 형식의 첫째 예외가 PresentationFrameWork.dll에서 발생했습니다. 추가 정보: '지정된 바인딩 제약 조건과 일치하는 'PapaZone.MainWindow' 형식에 대한 생성자 호출에서 예외가 throw 되었습니다.' 줄 번호 '21' 및 줄 위치 '9' 이 예외에 대한 처리기가 있으면 프로그램을 안전하게 계속할 수 있습니다. [] 이 예외 형식이 throw되면 중단 ================================== 위 Xaml 오류 메세지만으로는 내용 추적 불가하여, 도대체 뭔가 했다. 검색해도 뚜렷한 답변은 없었지만, 여러가지 의견을 종합해 보면 아래와 같다. 1. xmlns 관련 파일 과 관련된 파일 로딩 실패 이거나, 2. 신규로 추가된 namespace 에 속한 태그 사용시 오류로 판단되어 태그 하나씩 삽입하며 테스트 해봐야 한다고 함. 해결한 지금에 원인을 보면, xaml 에서 clr-namespace 로 추가된 항목들이 로딩에 실패해서 발생한 것이며, 추가된 항목은 있었으나, 이것과 연결된 파일이 없어서 로딩되지 않는 것이 문제였다. 오늘도 즐거운 하루~~

[MSSQL] SQL Server 에 원격 접속을 못하는 경우 조치 방법

[MSSQL] SQL Server 에 원격 접속을 못하는 경우 조치 방법 내부 오류 추적 결과 다음과 같이 나옴. [Microsoft][ODBC Driver 13 for SQL Server]TCP Provider: 대상 컴퓨터에서 연결을 거부했으므로 연결하지 못했습니다. SqlState : 08001, NativeError : 10061 오류 원인과 처리 1.SQL 서버 로그인 계정 틀린 경우 -> A.SQL Managerment Studio에서 사용할 DB 접속 '로그인' 사용할 계정의 아이디/암호 확인 2.TCP/IP 접속 권한이 없는 경우 -> A.SQL Server 구성 관리자를 실행에서 TCP/IP 허용 되어 있는지 확인 B. 서비스 포트 값이 (보통 1433) 맞는지 확인 C. 외부에서 접속하는 경우에는 방화벽 허용 되엉 있는지 확인 C. 서비스 재시작 3.Windows 인증 모드만 허용 인 경우 -> A.SQL Managerment Studio에서 사용할 DB 접속하고, 우클릭 하여 속성 정보 확인해서 B.연결에서 인증모드 '로그인' 사용할 계정의 아이디/암호 확인 4.'exec Sp_ReadErrorLog' 명령어를 사용해서, 로그인 실패 로그를 확인해서 원인을 분석한다.