proxy가 있는 환경에서 python pip 를 사용할때 

어떻게 해야할까 ㅎㅎ

 

아주 간단쓰 하당

 

 

 

 

1. 명령어에서 설정 추가 

>> pip config set global.proxy [proxy ip : proxy port]

 

 

 

2. 설정 파일에서 직접 수정 

C:\Users\AppData\Roaming\pip\pip.ini 파일에서 다음추가 

[global]

proxy = [proxy ip : proxy port]

 

 

3. pip 명령어 수행 할 때마다 proxy 옵션 추가

예시

 

>> pip install --proxy [proxy ip : proxy port] django

 

>> pip install --proxy [proxy ip : proxy port] djangorestframework

 

 

 

 

사실 3번은 넘나 귀찮은 일이고 

1번이나 2번으로 한번 설정해서

쓰면 아주 편할일~ ㅎㅎ

 

 

 

 

 

 

 

 

 

 

 

Django MVC 패턴


Django 도 MVC (Model View Controller) 의 패턴을 따른다.


Model : models.py
View : template (index.html)

Controller : views.py

 

동작 순서는 다음과 같다.

 

mysite/urls.py로 가서 해당 urlpattern 본다. 

우리는 여기서 http://localhost:8000/polls를 호출 했으니, 

 

mysite/urls.py

from django.contrib import admin
from django.urls import path , include

urlpatterns = [
    path('polls/' , include('polls.urls')),
    path('admin/', admin.site.urls),
]

 

해당 url을 따라서 polls/urls.py를 따라간다.

 

polls/urls.py

from django.urls import path

from . import views
app_name = 'polls'
urlpatterns =[
  path('', views.IndexView.as_view(), name='index'),
  path('/', views.DetailView.as_view(), name='detail'),
  path('/results/', views.ResultsView.as_view(), name='results'),
  path('/vote/', views.vote, name='vote'),
 ]

 

여기에서 http://locahost:8000/polls 를 호출했으니 indexView를 따라간다.

 

polls/views.py

class IndexView(generic.ListView):
  template_name = 'polls/index.html'
  context_object_name = 'latest_question_list'

  def get_queryset(self):
    """Return the last five published questions."""
    return Question.objects.order_by('-pub_date')[:5]


class DetailView(generic.DetailView):
  model = Question
  template_name = 'polls/detail.html'


class ResultsView(generic.DetailView):
  model = Question
  template_name = 'polls/results.html'


def vote(request, question_id):
  question = get_object_or_404(Question, pk=question_id)
  try:
    selected_choice = question.choice_set.get(pk=request.POST['choice'])
  except (KeyError, Choice.DoesNotExist):

    return render(request, 'polls/detail.html', {
      'question': question,
      'error_message': "You didn't select a choice.",
    })
  else:
    selected_choice.votes += 1
    selected_choice.save()
    return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

 

여기서 index.html을 호출 해서 화면을 보여준다.

 

polls/templates/polls/index.html

 

{% if latest_question_list %}
<ul>
          {% for question in latest_question_list %}
<li><a href ={% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
          {% endfor %}

</ul>

{% else %}

No polls are available.


{% endif %}

 

이런식으로 구동되고,

위에 붙인 소스가 주요 코드이다.

 

 

 

ㅎㅎ mvc 패턴은 생각보다 익숙하지만

python 문법이나 django 모두 생소해서

어려운 부분이 많은것 같다..

그리고 python은 주로 backend로 난 이용할것 같은데.. front보다는

그부분에 대해서 어떻게 구현할지를 더 고민해보아야겠다..

 

그리고 깊이를 익히기 위해선 책을 한권 빌려서 보는게 빠를것 같다 

튜토리얼은 그래도 한번 가볍게 따라하기 좋은것 같다 역시

 

 


참고

https://docs.djangoproject.com/ko/3.0/intro/tutorial03/

 

첫 번째 장고 앱 작성하기, part 3 | Django 문서 | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com

 

ㅎㅎ 저번 포스팅에 Django 프로젝트까지 생성해 보았다.

그다음 만든 프로젝트를 구동해보자

 

 

1. 앱 만들기

 

이제 앱을 만들어보자ㅏ

>>python manage.py startapp polls

 

 

그런데, 여기서 잠깐

프로젝트와 앱이 뭐가다를까?

 

앱은 웹 로그 시스템, 공개 레코드 데이터베이스 또는 소규모 설문 조사 앱과 같은 작업을 수행하는 웹 애플리케이션

 

프로젝트는 특정 웹 사이트에 대한 구성 및 앱 모음.

프로젝트에는 여러 앱이 포함될 수 있고. 앱은 여러 프로젝트에있을 수 있다.

 

 

그러면 polls라는 디렉토리가 생기며 그안에는 다음과 같은 파일이 생성되어져 있다.

 

polls/
    __init__.py
    admin.py
    apps.py
    migrations/
        __init__.py
    models.py
    tests.py
    views.py

 

 

 

2. DATABASE 설치

 

python에서 SQLite를 기본 제공해서 설치안해도 된다.

 

mysite/settings.py안에 여러 설정이 있는데 그중,

DATABASE 설정을 바꿔주면 다른 DB도 사용 가능하다.

 

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

 

 

mysite/setting.py안의 INSTALLED_APPS에는 Django와 함께 딸려오는 앱을 포함한다. 필요없는 앱은

주석처리 해주면 된다.

 

django.contrib.admin -- 관리용 사이트. 곧 사용하게 될 겁니다.
django.contrib.auth -- 인증 시스템.
django.contrib.contenttypes -- 컨텐츠 타입을 위한 프레임워크.
django.contrib.sessions -- 세션 프레임워크.
django.contrib.messages -- 메세징 프레임워크.
django.contrib.staticfiles -- 정적 파일을 관리하는 프레임워크.

 

다음 앱들도 DB가 필요한데, 

다음 명령어를 수행시켜 데이터베이스를 만들어주자

 

>>python manage.py migrate

 

 

3. 모델만들기

Django는 ORM (Object Relational Mapping)을 지원해,

DB와 데이터 모델클래스를 연결해준다고 하였다.

 

그래서 모델을 만들어주면, 데이터베이스를 그에 맞게 반영해 줄 수 있다.

 

1. 다음과 같이 polls/models.py를 수정해주고 

from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

 

2. 해당 앱도 DB에 반영 시켜주세요~ 라는걸 mysite/settings.py에서 INSTALED_APPS에 포함시켜준다. 

 

INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

 

3. 다음 명령어를 통해 변경된 migrations을 만들어준다.

 

>> python manage.py makemigrations polls

 

그러면 polls/migrations/하위에 001_initial.py 파일이 생성되는데

 

다음 명령어로 해당 migrations을 반영해준다.

>>pythjon manage.py sqlmigrate polls 0001

 

 

 

 

python manage.py makemigrations을 통해 이 변경사항에 대한 마이그레이션을 만드세요.


python manage.py migrate 명령을 통해 변경사항을 데이터베이스에 적용하세요.

 

 

3. 관리자 생성

>> python manage.py createsuperuser

 

 

이후 id/ pw 를 치고

 

서버기동 ( python manage.py runserver) 하고 , 

 

http://localhost:8000/admin으로 들어가면 어드민 페이지에 접속할 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 


참고

https://docs.djangoproject.com/ko/3.0/intro/tutorial01/

 

첫 번째 장고 앱 작성하기, part 1 | Django 문서 | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com

 

이글은 Django의 튜토리얼을 개인적으로 따라서 해본 글이다

그러고 개인적으로 정리하고자 한다 '-'

 

 


 

1. Django 란?

파이썬 웹 서버 프레임워크이다.

 

가장 특징적인건 ORM (Object Relational Mapping)을 지원한다는 점이다.

ORM은 DB와 데이터 모델 클래스를 연결해준다.

 

그리고 자동으로 관리자화면을 구성해준다..

이부분은 튜토리얼을 따라해보면서 봤는데 신기했다 ㅎㅎ 그리고 꽤 편리해서

잘 이용하면 유용할것 같다란 생각을 했다.

 

 

 

2. Python , Django 설치하기

 

https://www.python.org/downloads/

 

여기서 맞는 os를 선택해서 window일경우 bit도 보고,,

나는 window 64bit라

 

Windows x86-64 executable installer

를 선택해서 설치해 주었다

 

설치할 때 주의 사항은

Path 추가하기를 체크를 꼭 해야한다,, 

 

그이후 cmd 창에서 다음 명령어를 쳐서 설치가 잘 되었는지 확인해준다.

>>python --version

Python 3.7.7

이게 안됐을경우 환경변수를 확인해보자..!

 

 

이제 Django를 설치해주자 proxy가 없는 환경이라면, --proxy 를 빼고 설치해주면된다.

(django만 설치해줘도된다..)

>>pip install --proxy http://proxy_id:proxy_port pylint
>>pip install --proxy http://proxy_id:proxy_port django
>>pipi nstall --proxy http://proxy_id:proxy_port djangorestframework

 

설치가 잘 됐는지, Django 버전도 확인해보자

 

>> python -m django --version

3.0.4

 

 

3. Django 프로젝트 만들기

cmd 창에서 프로젝트를 만들고 싶은 경로에 다음 명령어를 쳐준다.

>>django-admin startproject mysite

 

여기서 mysite는 프로젝트명이다. 그럼 프로젝트가 만들어지고 

 

 

경로에 다음과 같은 파일이 생성 되어있을 것이다.

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        asgi.py
        wsgi.py

 

그리고 만든 프로젝트를 구동해보자

>> python manage.py runserver

 

 

ㅎㅎ 이번편은 여기까지하고 다음번에 

Django 프로젝트를 구현해보고자 한다.

 

 

 

 


참고

https://docs.djangoproject.com/ko/3.0/intro/tutorial01/

 

첫 번째 장고 앱 작성하기, part 1 | Django 문서 | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com

 

ㅎㅎ

DB를 서버에 설치 이후,

설정을 가볍게 이거저거 바꿀일이 있다

 

/etc/mysql/my.cnf 나

/etc/my.cnf 에 보통 있다.

 

해당 파일을 vi로 열어서 편집해서 저장한뒤,

DB를 재기동 하면된다.

 

$ vi /etc/my.cnf

 

 

1. 인코딩 : UTF8

 

가장 기본적은 인코딩 방식을 utf8로 바꾸는 것이다

[mysql]

default-character-set = utf8

 

[mysqld]

character-set-client-handshake=FALSE

init_connect="SET collation_connection = utf8_general_ci"

init_connect="SET NAMES utf8"

character-set-server = utf8

collation-server = utf8_general_ci

  

[client]

default-character-set = utf8

 

DB 재기동

$ service mysqld restart

 

 

2. query 대소문자 구분 안함

그리고 보통 많이 하는게 query날렸을때 대소문자를 구분 안하도록 설정해 주는 것이다.

 

show variables like 'lower_case_table_names';

 

다음 쿼리로 확인 해보면 

0일 경우, 대소문자 구분하고

1일 경우, 대소문자 구분을 안한다 그래서 

[mysqld] 에 추가 한뒤, 재기동 해준다~

 

[mysql]

default-character-set = utf8

 

[mysqld]

character-set-client-handshake=FALSE

init_connect="SET collation_connection = utf8_general_ci"

init_connect="SET NAMES utf8"

character-set-server = utf8

collation-server = utf8_general_ci

lower_case_table_names=1

  

[client]

default-character-set = utf8

 

3. DB max connection

   SHOW VARIABLES LIKE '%wait_timeout%';

  SHOW VARIABLES LIKE '%max_connection%'; // 접속수 

      

 

 

4. DB 재기동 없이 변수값 변경하기

 

set global 변경값;

ex) setl global lower_case_table_names=1;

 


참고

 

http://wincloud.link/pages/viewpage.action?pageId=9469960

 

MySQL 기본 인코딩을 UTF8 로 변경 - Linux - Confluence.winCloud.Link

MySQL 기본 설정으로는 한글이 모두 ? 로 나오면 깨져서 보이게 된다. 이를 해결하기 위하여, 기본 인코딩을 UTF8 로 변경한다. 단계별 안내 # 설정값 확인 mysql> show variables like 'c%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+-------------------

wincloud.link

http://blog.naver.com/PostView.nhn?blogId=juner84&logNo=100124891560&categoryNo=23&viewDate=¤tPage=1&listtype=0

 

[Mysql] mysql 중단 없이 mysql variable 변경

# mysql variable 변경 mysql을 사용하다 보면 이것저것 설정을 변경할 필요가 있다. 기본적인 설정은 /etc...

blog.naver.com

 

'DEVELOP > DB' 카테고리의 다른 글

[mySql] 계정 생성 및 권한 설정  (0) 2020.05.25
[MariaDB] general log 설정하기  (0) 2020.05.25
NewSql 이란? All in one DBMS  (0) 2019.12.16
NoSql DB 종류  (0) 2019.12.13
DB(database)의 종류  (0) 2019.12.11

이전에 RestTemplate으로 api get하기 란 글을 

블로그에 썼는데.. 

 

난 내가 개발한거 정리하려고 쓴건데 조회수가 생각보다 잘나와서 놀랬다 ;;

 

그이후 Retrofit이란 것도 써봤다

 

retorifit을 써보니 Feign은 크게 다른게 없는거 같았다..

그전에 쓸때 retrofit에 있는 제약사항이 있었는데.. Feign은 해당 제약사항이 없는진 잘모르겠다.

 

c.f ) Retrofit에서 제약사항이란?

Retrofit에서 인터페이스 하나당 서비스 하나를 구성해야한다는 것이다.

나는 비지니스 적으로 한 인터페이스를 구성해놓고 그것을 extends해서 쓰고싶었다.. 그런데 retrofit에서 해당 기능을 제공안하더라... ;ㅁ; 

 

It's not possible to have a base Retrofit interface.

Retrofit favors composition over inheritance. One interface per service.

So as you already found out, the only solution is to create three independents interfaces.

 

 

https://stackoverflow.com/questions/34181208/java-lang-illegalargumentexception-api-interfaces-must-not-extend-other-interfa

 

다음글에서 2.7.0에는 이러한 제한을 없앤다고 하는데 현재 메이븐에는 2.6.1 버전까지 밖에 나오지 않았다.

그래서.. extends하도록은 설계하지 못하였다,,(API interfaces must not extend other interfaces.)

 

https://github.com/square/retrofit/issues/504

 

 

 

ㅎㅎ.. 말이 길어졌는데

Feign의 사용법에 대해서 그렇담 알아보자!

(다음엔 Retrofit에 대해서 써야겠다ㅋㅅㅋ)

 

 


 

1. maven일 경우 pom.xml에 dependency 추가 

 

<dependency>

   <groupId>org.springframework.cloud</groupId>

   <artifactId>spring-cloud-starter-openfeign</artifactId>

</dependency>

 

2. Application.java 파일에 @EnableFeignClients annotation 추가

이것은 난 Feign을 쓸거야~ 라고 알려주는 것이다

 

package com.example.feignTest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableFeignClients // Feign Client를 사용할 것임을 알려줌
@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

 

@EnableFiegnClients는 돌아다니면서 @FeignCleint를 찾아 구현체를 만들어 준다.

root package에 있어야하며 아니면 basePackage를 지정해 주어야한다.

 

3. Feign Cleint 작성

인터페이스로 작성하고 인터페이스 위에 @FeignClient annotation을 넣어준다.

 

그리고 가져와야되는 url이랑 configuration이 필요하다면 작성해서 넣어주면 된다.

package com.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name="test", url="http://localhost:8000" , configuration={FeignConfiguration.class})
public interface TestClient {

    @GetMapping("/test")
    String test(@PathVariable("id") int id);
}

 

 

5. Client 사용(호출)

 

이제 서비스에서 해당 Client만 주입해서 API만 호출해주면 된다.

package com.service;

import com.client.TestClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TestService {
    @Autowired
    TestClient testClient;


    public String test(id) {
     ~~~

     testClient.test(id);

~~~


    }
}

 

 

 

참쉽죠잉~?

ㅎㅎ 더 세부적인건 나중에 적어보도록 하겠다..

사실 이 밑에 있는 spring의 문서를 자세히 보는것이 가장 좋긴하다

 


참고

https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html

 

7. Declarative REST Client: Feign

Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable

cloud.spring.io

https://woowabros.github.io/experience/2019/05/29/feign.html

 

우아한 feign 적용기 - 우아한형제들 기술 블로그

안녕하세요. 저는 비즈인프라개발팀에서 개발하고 있는 고정섭입니다.이 글에서는 배달의민족 광고시스템 백엔드에서 feign 을 적용하면서 겪었던 것들에 대해서 공유 하고자 합니다.

woowabros.github.io

https://velog.io/@skyepodium/2019-10-06-1410-%EC%9E%91%EC%84%B1%EB%90%A8

 

Feign Client 알아보기

2. 사용법 1) 스프링부트 프로젝트 만들기 spring start에서 스프링부트 프로젝트를 만들었습니다. (maven, gradle 상관없습니다.) 라이브러리는 web만 넣어주었습니다. 스크린샷 2019-10-06 오후 2.57.09.png 2) feign client 라이브러리 넣기 - maven 일 경우 - gra...

velog.io

 

'DEVELOP' 카테고리의 다른 글

강화학습이란? ( feat. 지도학습)  (1) 2020.10.30
[Security] 사용자 인증방식 종류와 결정  (0) 2020.05.26
리눅스 alias 등록 방법  (0) 2020.05.18
OSI 7 계층 이해하기!!  (0) 2020.01.21
OAuth 2.0이란?  (0) 2020.01.06

 

Docker의 timezone 과 java application 의 timezone의 sync를 맞추자! 

혹은.. 서버의 timezone과 java application의 sync...

 

docker의 timezone을 설정하고, 

spring boot인 application 을 띄웠는데..

 

 

다음과 같이 localtime을 지정해주고 docker를 띄워주면

 

docker run -d -v /etc/localtime:/etc/localtime:ro

 

/ # date
Thu Mar 12 06:55:37 UTC 2020

date 명령어로 timezone이 잘 바뀐걸 확인 할 수 있다.

 

 

그런데..

spring의 log를 보면 timezone의 시간과 안맞는 것이다..

 

그래서 검색해보니 

log의 시간은 jvm의 시간을 물고가는데 

혹은, java application 단에서도 jvm의 시간을 가져오기 때문이다.

 

그래서 하단의 stack overflow를 보고 해결하였다. 한가지 옵션을 더주니 해결 되었다.

 

docker run -d -v /etc/localtime:/etc/localtime:ro -v /usr/share/zoneinfo/Asia/Seoul:/etc/timezone:ro

 

그리고 다시 재기동~ 후 확인해보니

date도, log도 모두 같은 시간인걸 확인하였다.

 

 

그런데 저 명령어가 무슨 의미가 있어서 잘되는지 알고 싶은데.. 

찾다가 정확하게 이해는 못하였다.

 

하단 github 참조

 

As I experience it, containers use their internal timezone, not the timezone of their host OS.

 

So, let's unravel this a little bit (hopefully).

  • containers share the kernel
  • the kernel tracks the "current time" (note this is "time", not "timezone"), and it is tracked simply as the "number of seconds since the epoch (1970-01-01 00:00:00 UTC)" (hence the name, "Unix Timestamp")
  • userspace (which includes tools like date) has a notion of "timezone", and it usually comes from "/etc/localtime" (but this does sometimes depends on the utility, some read "/etc/timezone" instead, and some update "/etc/localtime" from the contents of "/etc/timezone")

The Gentoo Wiki's "System time" entry also has some great information that helps untangle

 

 

저 말을 해석해보면.

컨테이너는 host OS의 timezone이 아니라 각각 내부의 timezone을 사용하고 

 

그아래 문구를 해석해보자면.. 결국 timezone은 여러군데서 읽어온다는 뜻인거 같다... 허허

 


 

 

그리고 찾다보니 docker가 아닌 서버에서도 이런 경우가 있는데 다음 블로그에 그 방법이 자세히 나와있다.

 

https://irontooth.tistory.com/47

 

java Calendar 시간과 서버시간 불일치 처리

1) Calendar runTimeCal = Calendar.getInstance(); System.out.println ("현재 타임존 : " + runTimeCal.getTimeZone().getDisplayName() ); TimeZone tz = TimeZone.getTimeZone("GMT+09:00"); runTimeCal.setTi..

irontooth.tistory.com

 

java -jar -Duser.timezone=Asia/Seoul 

해당방법처럼 매번 기동할때마다 이렇게 설정해주던가.. 아니면 start shell에 입력해주면 될거같다

아니면 

WAS에서 하는 방법도 있다.

 


 

참고 : 

 

https://stackoverflow.com/questions/34534079/how-to-sync-the-time-of-a-java-application-running-on-docker-container

 

How to sync the time of a java application running on docker container?

I am docker file like this: FROM anapsix/alpine-java:jre8 ADD service-god-sac-1.0.0-SNAPSHOT.jar app.jar ENTRYPOINT ["java", "-Xmx64m", "-XX:MaxMetaspaceSize=64m", "-jar", "/app.jar"] When I co...

stackoverflow.com

 

https://github.com/moby/moby/issues/3359

 

container timezone · Issue #3359 · moby/moby

As I experience it, containers use their internal timezone, not the timezone of their host OS. I currently work around this issue by providing a start script that takes a typezone parameter which i...

github.com

 

'DEVELOP > DevOps' 카테고리의 다른 글

내가 헷갈려서 쓰는 Git..기능  (0) 2019.07.12

Spring에서 Async처리를 해보겠다..!

 

블로그에 정리되어 있는게 많았는데 그중에 어떤 방법을 택할까 고민을 했다.

 

 

 

가장 간단한 방법으로 구현하였다.

 


 

@Async 

annotaion을 붙여주는 방법이다.

 

1. @EnableAsync로 async를 쓰겠다고 스프링에게 알린다.

2. 비동기로 수행되었으면 하는 method위에 @Async annotaion 을 붙인다.

3. method return 값은 void나 CompletableFuture<?>로 해주어야한다.

 

 

 

@EnableAsync은 Application을 run하는 데에다 붙여주거나,@Configuration annotaion 있는데 붙여주면 된다.

 

그리고 thread를 관리해주어야 하기 때문에 bean을 설정해준다.

 

@Bean
  public Executor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(2);
    executor.setMaxPoolSize(2);
    executor.setQueueCapacity(500);
    executor.setThreadNamePrefix("GithubLookup-");
    executor.initialize();
    return executor;
  }

 

spring boot 2.0이상이면, application.yml파일에 작성해도 auto configuration 으로 Excutor를 등록해준다.

 

 

이렇게해서,, 테스트를 해봤었는데 잘안되었다

 

이유는???

 

@Async를 활용하기 위해서는 몇가지 제약 조건이 있기 때문이다.

 

 

1.public method만 @Async가 가능하다. private는 불가능 
2.self-invocation(자가 호출)해서는 안된다. -> 같은 클래스 내부의 메서드를 호출하는 것은 안된다.

 

 

나같은 경우는 2번의 경우였다.

한 service에서 계속 function call을 내부적으로 하는데 

그중에 한, method만 비지니스적으로 async하게 call하고 싶었다.

 

 

그래서 찾은 방법은???

async해야 하는 method를 다른 service로 빼서 , 

기존 service에 AsyncService를 주입하고 (@Autowired)

async 해야하는 method에 @Async를 붙여준다음,

service에서 call 하면 되는 것이다 (간단간단 '-' 역시.. 알면 간단하다)

 

 

기존 service

@Service

public class 기존service{

@Autowired

AsyncService asyncService;

 

public void 해당method(){

      asyncService.asyncMethod();

   }

}

 

 

AsyncService

@Service

public class Asyncservice{

 

@Async

    ComletableFuture<OutVO>asyncMethod(){

      OutVO output = new OutVO();

 

       return ComletableFuture.completedFuture(output);

   }

}

 

 

 

그런데 도대체 왜그럴까?? ( 블로그 글 참조)

 

결론부터 말하면 AOP가 적용되어 Spring context에 등록되어 있는 빈 객체의 메서드가 호출되었을 때 스프링이 끼어들 수 있고 @Async가 적용되어 있다면 스프링이 메서드를 가로채서 다른 스레드(풀)에서 실행시켜주는 메커니즘이라는 것이다.

 

public이어야 가로챈 스프링의 다른 클래스에서 호출이 가능하고,

self-invocation이 불가능 했던 이유도 spring context에 등록된 빈의 메서드 호출 이어야

프록시를 적용 받을 수 있기에 내부 메서드 호출은 프록세 영향을 받지 않기 때문이다.

 

 

 

 

 


참고 사이트 :

https://spring.io/guides/gs/async-method/

 

Spring

Level up your Java code and explore what Spring can do for you.

spring.io

 

https://jeong-pro.tistory.com/m/187

 

How does @Async work? @Async를 지금까지 잘 못 쓰고 있었습니다(@Async 사용할 때 주의해야 할 것, 사용법)

@Async in Spring boot 스프링 부트에서 개발자에게 비동기 처리를 손쉽게 할 수 있도록 다양한 방법을 제공하고 있다. 대세는 Reactive stack, CompletableFuture를 쓰겠으나 역시 가장 쉬운 방법으로는 @Async..

jeong-pro.tistory.com

 

 

업무를 하다보니 

네트워크 기초가 부족하다는걸 절절히 느끼고

기초 책을 하나 빌려서 다보았당 '-'v(뿌듯)

 

그러니 대학교때 배웠던게 조금조금씩 기억도 나는거 같기두하구..

ㅋ_ㅋ;;

 

 

네트워크에서

OSI 7계층에 대해서 공부하고

 

데이터가 전달될때  OSI 모델에서 어떤일이 일어나나를 봐보겠다

 

 

 


 

1. OSI 계층

 

 

 

이 그림에서 OSI 계층이 무슨 일을 하는지 개략적으로 잘 보여준다.

 

1. 물리계층 (데이터 -> 전기신호 변환)

-  OSI 모델의 최하위 계층으로, 데이터를 전송하기 위해 시스템간의 물리적인 연결을 하고 전기 신호의 변호나 및 제어하는 역할 담당

- 전송 매체를 통해 데이터를 통신할 수 있는 전기적인 신호로 바꾸어 전송하는 일 수행

 

2. 데이터 링크 계층 ( MAC주소)

- 네트워크 기기 간에 데이터를 전송하고 물리주소를 결정

- 스위치( MAC 주소 테이블 )

 * 허브와 달리 데이터 충돌 발생하지 않음 

 * MAC주소 테이블이 있음 : 스위치의 포트번호와 , MAC주소가 등록되어 있는 데이터베이스

 

같은 네트워크내,,,

 

 

3. 네트워크 계층 ( 다른 네트워크와 통신 / ip)

- 다른 네트워크와 통신하기 위한 경로 설정을 위해 라우터를 통한 라우팅을 하며 패킷 전송 담당

- 라우터

 * 서로다른 네트워크를 연결해 줄는 장치

 * 현재의 네트워크에서 다른네트워크로 패킷을 전송 할 수 있다.

 

4. 전송 계층 ( 포트번호 )

- 신뢰할 수 있는 데이터를 순차적으로 전달하는 역할

- 상위 계층들이 데이터 전달의 유효성이나 효율성은 신경쓰지 않고, 데이터가 중복되거나 누락되지 않고 오류 없이 순서에 맞게 전송 되도록 관리

 

5. 응용계층 ( 서비스 제공)

- 시스템 간의 응용 처리는 상호간에 통신하면서 일련의 업무를 처리할 수 있도록 필요한 서비스 기능 제공

- 이메일 , 파일 전송, 웹 사이트 조회 등 애플리케이션에 대한 서비스 제공 

 

 

 

 

2. 데이터 전송 흐름

 

 

 

이 그림에서 컴퓨터에서 웹서버로 데이터 흐름이 이동하는데

스위치 A-> 라우터 A -> 라우터 B -> 스위치 B를 거친다.

 

스위치 A에서는 데이터 링크 계층에서 데이터를 전기신호로 변환하여 라우터 A로 전송한다.

 

라우터 A에서는 데이터 링크 계층에서 이더넷프레임의 목적지 MAC주소와 자신의 MAC주소를 비교한다.

주소가 같으면? 이더넷 헤더와 트레일러를 분리하는 역캡슐화를 수행

 

네트워크 계층에 전달해 라우팅 테이블과 목적지 IP주소를 비교한다.

현재 출발지 주소 192.168.1.10을 라우터 외부IP주소인 172.16.0.1로 변경한다.

 

라우터B에서는 외부 IP주소 172.16.0.1을 내부IP주소 192.168.10.1로 변경한다.

 

 

 

 

 

 

해당 그림은 전체 데이터 흐름의 OSI 계층을 지나가는 흐름을 그린 것이다.

 

 

 

3. OSI 계층별 캡슐화 / 역캡슐화

 

 

 

데이터를 보낼때 각계층에서 헤더를 붙여 나가는 것을 캡슐화 라고 한다.

그리고 반대로,

데이터를 수신할 대, 각 계층에서 헤더를 제거해 나가는 겻을 역캡슐화라고 한다.

 

 

각 계층에 필요한 정보를 덧붙여서 다음 계층으로 보내준다.

그리고 정보를 받을때는 해당 계층에 필요한 정보면 확인하고

맞으면 다음 계층으로 통과시키고 아니면 스탑,,

 

 

 

 


모든 사진의 출처

: 모두의 네트워크 (길벗 출판사)

 

 

 

BFS를 연습해보기 위해서 

이 문제를 풀어보았다.

 

 

 

 

 

main에서는 먼저 데이터를 map에 넣어주고

가장 중요한 것은 

해당단지마다 bfs를 돌려준다는 것이다...

 

한번에 bfs를 돌려서 전체 탐색을 하는 것이 아니라

단지마다 bfs를 돌려서

해당 단지에 집이 몇가구 있는지를

세어야 하기 때문이다.

 

그리고 몇단지인지도 세어야 하기때문에 

사실 bfs를 처음 호출되는 횟수만큼이

단지 수라고 볼 수 있겠다.

 

queue에 데이터를 관리하기 쉽게 pos에

정점 y와x를 선언해서

class를 선언해주었다.

 

 

 

그리고 가장 중요한

bfs method

 

먼저 queue에 값을 넣어주고

 

queue가 빌때까지

while문을 돌려준다.

 

그리고 d 배열 

그니깐 아래,위,오른쪽,왼쪽으로 

이동할 좌표를 입력해놓은 배열을

for를 돌면서

새로운 좌표를 구해준다

 

그게 newY, newX

 

구한 새로운 좌표값을 먼저

 

1. 경계값을 체크해준다.

( 0보다 큰지, N 보다 작은지)

2. 그리고 단지에 포함되는지를 체크한다

map[newY][newX] == 1

3. 그리고 방문한 적이 있는지? 도 체크해준다

visited[newY][newX] == fasle

 

해당 조건들이 모두 통과가 되었으면

queue에 들어갈 자격이 된닷!!

 

그렇다면 

queue에 값을 넣어주고 

방문했다고 체크해주고

그리고 단지내 가구수의 count 를 늘려준닷

 

 

그리고 해당 queue가 비면

(단지내 가구를 모두 방문했으면)

해당 단지내 가구수 가 나왔기 때문에

정답인 ArrayList에 count 배열을 넣어준다.

 

 

그리고 맨마지막에 출력할때에는

ArrayList의 수가 총 단지의 수이고

각 count가 단지내 가구 수가 된다.

 

그래서 ArrayList를 라이브러리를 

이용해 정렬해주고

 

출력해주면된다~~

 

 

+ Recent posts