요즘에 https://github.com/square/okhttp은 점차 안드로이드 진영에서 인정받으면서 서버단에서 많이 쓰기 시작하고 있다. 

okhttp에 pooling이 내부적으로 되어 있어서, 편하게 사용가능하다.



OKHttpClient를 생성할 때 OKHttpClient.Builder를 호출하는데, 기본 생성자인 ConnectionPool을 생성하면서 5개 connection을 자동으로 생성한다.





https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/OkHttpClient.java



https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/OkHttpClient.java#L487



https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/ConnectionPool.java#L85


 

public ConnectionPool() {

this(5, 5, TimeUnit.MINUTES);

}



Posted by 김용환 '김용환'


scala 프로젝트에서 사용할만한 scala- elasticsearch 라이브러리는 sksamuel이 가장 좋은 것 같다. (아직 갈길이 멀지만.)



sksamuel의 HTTPClient을 잘 사용하고 있다. 

val result = client.execute {
val req = search(indexName).
query {
bool {
//..
}

queryStatement = client.show(req)
req
}
}


중요한 것은 비동기로 되어 있어서 쭉 지나가 버린다. 


동기(synchronous) 코드로 개발하려면 Await.result 또는 Await.ready를 사용한다. 




Await.result를 사용하는 코드는 간단하다. 내부적으로 Future[Either[]] 형태로 Right/Left를 먼저 써야 한다. 


import scala.concurrent.duration._
val response = Await.result(result, atMost = 5.second)

response match {
case Right(success) => {
// ..

}
case Left(e) => {
//..
}
}



Await.ready와 Await.result는 exception 처리방식이 조금 다르다. 나는 아직 완벽한 프로그램이 아니라서 차라리 crash가 나은 듯해서 Await.result를 사용해봤다.



exception이 발생하면 Await.result는 crash exception이 발생하고, 

Await.ready는 exception을 Failure로 감싼다. 

 


Posted by 김용환 '김용환'

트위터는 이미 mesos 기반을 쓰고 있고..


넥플릭스는 mesos 기반의 컨테이너 개발이 진행 중이다. 


https://queue.acm.org/detail.cfm?id=3158370



Posted by 김용환 '김용환'


centos 7.2에서 2017.1.25부터 docker yum 설치가 실패하고 있다. 


다음 의존성 때문인 것 같다. 


libsemanage-2.5-8.el7.x86_64 conflicts selinux-policy-base < 3.13.1-66\\n--> Finished Dependency Resolution\\n You could try using --skip-broken to work around the problem\\n You could try running: rpm -Va --nofiles --nodigest



문제 해결이 쉽지 않아 os를 7.4로 올리니 정상적으로 docker를 설치할 수 있었다..

Posted by 김용환 '김용환'



kubernetes의 네트워킹과 Pod, Service, ServiceNetwork의 개념, 오버레이 네트워크(https://en.wikipedia.org/wiki/Overlay_network), 디플로이(https://kubernetes.io/docs/concepts/workloads/controllers/deployment/), kube-proxy를 잘 설명한 글이 소개한다.





1. Understanding kubernetes networking: pods


https://medium.com/google-cloud/understanding-kubernetes-networking-pods-7117dd28727



(주요 그림)




2. Understanding kubernetes networking: services


https://medium.com/google-cloud/understanding-kubernetes-networking-services-f0cb48e4cc82



(주요 그림)



내부적으로 동작하는 netfilter의 중요성을 설명한 내용이 포함되어 있다. 


3. Understanding kubernetes networking: ingress


https://medium.com/google-cloud/understanding-kubernetes-networking-ingress-1bc341c84078


(주요 그림)



Posted by 김용환 '김용환'



https://blog.docker.com/2018/01/docker-mac-kubernetes/



이제 맥 docker에서 k8s를 사용할 수 있게끔 한다고 한다.






Posted by 김용환 '김용환'




https://gravitational.com/blog/running-postgresql-on-kubernetes/

postgres를 그냥 k8s에서 운영했다가 데이터 손실되었다고 한다.

stateful(https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) 써서 HA를 유지하는 것이 좋다는 얘기가 있다. 


stateful은 중요하다.



Using StatefulSets

StatefulSets are valuable for applications that require one or more of the following.

  • Stable, unique network identifiers.
  • Stable, persistent storage.
  • Ordered, graceful deployment and scaling.
  • Ordered, graceful deletion and termination.
  • Ordered, automated rolling updates.

In the above, stable is synonymous with persistence across Pod (re)scheduling. If an application doesn’t require any stable identifiers or ordered deployment, deletion, or scaling, you should deploy your application with a controller that provides a set of stateless replicas. Controllers such as Deployment or ReplicaSet may be better suited to your stateless needs.

Limitations

  • StatefulSet was a beta resource prior to 1.9 and not available in any Kubernetes release prior to 1.5.
  • As with all alpha/beta resources, you can disable StatefulSet through the --runtime-config option passed to the apiserver.
  • The storage for a given Pod must either be provisioned by a PersistentVolume Provisioner based on the requested storage class, or pre-provisioned by an admin.
  • Deleting and/or scaling a StatefulSet down will not delete the volumes associated with the StatefulSet. This is done to ensure data safety, which is generally more valuable than an automatic purge of all related StatefulSet resources.
  • StatefulSets currently require a Headless Service to be responsible for the network identity of the Pods. You are responsible for creating this Service.





Posted by 김용환 '김용환'

일래스틱서치에 uuid로 소팅하고 싶은데, 에러가 발생했다. 


(쿼리)

 curl -XGET 'localhost:9200/google_plus_data/_search?pretty' -H 'Content-Type: application/json' -d'

{

  "query": { "match_all": {} },

  "size": 10,

  "sort": [ 

            { "@timestamp": "desc" } ,

            { "_uuid": "asc" } 

          ]

}'




(에러)


"reason" : "Fielddata is disabled on text fields by default. Set fielddata=true on [_uuid] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."




에러 관련해서 문서를 보면 먼가 작업을 해야 할 것 같지만..

https://www.elastic.co/guide/en/elasticsearch/reference/5.0/fielddata.html


uuid는 keyword라는 필드가 있어서.. 사용하면 작 동작한다.



 curl -XGET 'localhost:9200/google_plus_data/_search?pretty' -H 'Content-Type: application/json' -d'

{

  "query": { "match_all": {} },

  "size": 10,

  "sort": [ 

            { "@timestamp": "desc" } ,

            { "_uuid.keyword": "asc" } 

          ]

}'





Posted by 김용환 '김용환'


python에는 Java의 toString()과 같은 문법이 있다. 




>>> import datetime

>>> today = datetime.datetime.now()

>>> str(today)

'2018-01-23 14:49:37.284361'

>>> repr(today)




>>> f=1.1111111111111111

>>> str(f)

'1.11111111111'

>>> repr(f)

'1.1111111111111112'




str은 사용자가 보기 편하게 "비공식"적으로 쓰는 문자열(반드시) 표현법이고,

repr은 시스템에서 구분하기 위한 공식적연 표현법이며 문자열이 아니어도 된다.



https://docs.python.org/3.7/reference/datamodel.html#object.__repr__


object.__repr__(self)

Called by the repr() built-in function to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned. The return value must be a string object. If a class defines __repr__() but not __str__(), then __repr__() is also used when an “informal” string representation of instances of that class is required.


This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.


object.__str__(self)

Called by str(object) and the built-in functions format() and print() to compute the “informal” or nicely printable string representation of an object. The return value must be a string object.


This method differs from object.__repr__() in that there is no expectation that __str__() return a valid Python expression: a more convenient or concise representation can be used.


The default implementation defined by the built-in type object calls object.__repr__().



Posted by 김용환 '김용환'

scala retry 참조 코드

scala 2018.01.23 11:33

scala retry 참조 코드 



https://stackoverflow.com/questions/7930814/whats-the-scala-way-to-implement-a-retry-able-call-like-this-one





import util._

object RetryUtils {

@annotation.tailrec
def retry[T](n: Int)(fn: => T): T = {
Try { fn } match {
case Success(x) => x
case _ if n > 1 => retry(n - 1)(fn)
case Failure(e) => throw e
}
}
}



예제 코드


val retryResult = retry(3) {
if (validateObject(esClient)) {
esClient
} else {
null
}
}


Posted by 김용환 '김용환'