22 Haziran 2017 Perşembe

Tomcat server.xml

Giriş
TOMCAT_HOME\conf\server.xml dosyadır. Açıklaması şöyle
Tomcat can work in 2 modes:

BIO (one thread per connection), or NIO (many more connections than threads).

Tomcat7 is BIO by default, although consensus seems to be "don't use Bio because Nio is better in every way". You set this using the "protocol" parameter in the server.xml file - BIO will be "HTTP1.1" or "org.apache.coyote.http11.Http11Protocol" and NIO will be "org.apache.coyote.http11.Http11NioProtocol"
Şeklen şöyledir.
<?xml version='1.0' encoding='utf-8'?>

<Server...>
  <Listener.../>

  <GlobalNamingResources>
    <Resource.../>
  </GlobalNamingResources>

  <Service name="Catalina">
    <Connector.../>
    <Engine...>
      <Realm.../>
      <Host...>
        <Context.../> 
        <Valve.../>
      </Host>
    </Engine>
  </Service>
</Server>

Cluster
Şöyle yaparız.
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
             channelSendOptions="8">

  ...
</Cluster>
Connector
BIO için
org.apache.coyote.http11.Http11Protocol
NIO için
org.apache.coyote.http11.Http11NioProtocol
kullanılır.

Connector - AJP
Cluster şeklinde kullanmak için şöyle yaparız.
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
Örnek
Şöyle yaparız.
<Connector port="8012" protocol="AJP/1.3" redirectPort="8446"
  connectionTimeout="10000" keepAliveTimeout="10000" />
httpd'ye şöyle yaparız.
vi /etc/httpd/conf.d/mydomain.com.conf

<VirtualHost www.mydomain.com:80>
    ServerName www.mydomain.com
    ServerAlias mydomain.com
    ErrorLog /var/log/httpd/mydomain_com_error.log
    CustomLog /var/log/httpd/mydomain_com_requests.log combined
    ProxyPass / ajp://my.public.ip.addr:8012/
    ProxyPassReverse / ajp://my.public.ip.addr:8012/
</VirtualHost>
Connector - connectinTimeout
Şöyle yaparız.
<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" 
       URIEncoding="UTF-8"/>
Connector - Http
server.xml dosyasında Connector ayarı değiştiriliyor. Örnek'te port 80 yerine 8080 yapılabilir.
<Connector port="8080" maxHttpHeaderSize="8192"
  maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
  enableLookups="false" redirectPort="8443" acceptCount="100"
  connectionTimeout="20000" disableUploadTimeout="true"
  URIEncoding="UTF-8"
/>
Connector - Https
Tomcat ile https kullanmak için server.xml dosyasında bir connector tanımı olmalı. Şöyle yaparız.
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
  maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
  clientAuth="false" sslProtocol="TLS" />
Connector - keystore
Şöyle yaparız.
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
  maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
  clientAuth="true" sslProtocol="TLS"
  keystoreFile="/etc/pki/mykeystore.jks"
  keystoreType="JKS" keystorePass="password"
  truststoreFile="/etc/pki/server_truststore.jks"
  truststoreType="JKS"   truststorePass="password"/>
Connector - maxConnections
Açıklaması şöyle. NIO için varsayılan değer 10,000
The maximum number of connections that the server will accept and process at any given time. When this number has been reached, the server will accept, but not process, one further connection. This additional connection be blocked until the number of connections being processed falls below maxConnections at which point the server will start accepting and processing new connections again. Note that once the limit has been reached, the operating system may still accept connections based on the acceptCount setting. The default value varies by connector type. For BIO the default is the value of maxThreads unless an Executor is used in which case the default will be the value of maxThreads from the executor. For NIO the default is 10000. For APR/native, the default is 8192.
Note that for APR/native on Windows, the configured value will be reduced to the highest multiple of 1024 that is less than or equal to maxConnections. This is done for performance reasons. If set to a value of -1, the maxConnections feature is disabled and connections are not counted.
Connector - maxHttpHeaderSize
Şöyle yaparız
<Connector port="8443" 
  maxHttpHeaderSize="8192" 
  maxThreads="150" 
  minSpareThreads="25" 
  maxSpareThreads="75" 
  enableLookups="false" 
  disableUploadTimeout="true" 
  acceptCount="100" 
  scheme="https" 
  secure="true" 
  SSLEnabled="true" 
  clientAuth="true" 
  sslProtocol="SSL/TLS" 
  keystoreFile="C:/EBCM_Client_TEST.pfx"
  keystorePass="allianzebcm"
  keystoreType="PKCS12"/>
Connector - maxThreads
Açıklaması şöyle
Each incoming request requires a thread for the duration of that request. If more simultaneous requests are received than can be handled by the currently available request processing threads, additional threads will be created up to the configured maximum (the value of the maxThreads attribute). If still more simultaneous requests are received, they are stacked up inside the server socket created by the Connector, up to the configured maximum (the value of the acceptCount attribute). Any further simultaneous requests will receive "connection refused" errors, until resources are available to process them.
Açıklaması şöyle
If you're using NIO then actually "maxConnections=1000" and "maxThreads=10" might even be reasonable. The defaults are maxConnections=10,000 and maxThreads=200. With NIO, each thread can serve any number of connections, switching back and forth but retaining the connection so you don't need to do all the usual handshaking which is especially time-consuming with HTTPS but even an issue with HTTP. You can adjust the "keepAlive" parameter to keep connections around for longer and this should speed everything up.
NIO modda kaç thread kullanmak istediğimizi belirtmek için şöyle yaparız.
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
       maxThreads="250" SSLEnabled="true" scheme="https" secure="true"
       clientAuth="false" sslProtocol="TLS" connectiontimeout="20000"/>
Connector - redirectPort
Niçin redirect kullanırız sorusunun cevabı şöyle. Http'den Https'e yönlendirmek için kullanılabilir.
For usability reasons you need to offer a redirect to HTTPS from all HTTP URL:s. Otherwise first time visitors who simply enter example.com/some/page into the URL bar of the browser will be greeted by a connection error.
Bazı siteler HSTS header kullanıyor. Bu header ile browser'da HTTPS Everywhere varsa kendiliğinden http'den https'e istek gönderiyor. Yani redirect'e gerek kalmıyor.

HTTPS Everywhere'in açıklaması şöyle
HTTPS Everywhere is client-side, and HSTS is server-side.
Şöyle yaparız.
<Connector port="80" protocol="HTTP/1.1" 
           connectionTimeout="20000" 
           redirectPort="8443" />
Connector - URIEncoding
Http Get isteğinde HttpServletRequest sınıfı Http standardında belirtildiği gibi gönderilen parametreleri Latin 1 olarak string'e çevirir. Eğer UTF-8 olarak çevirsin istersek bunu URIEncoding ile belirtiriz.
Şöyle yaparız.
<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" 
       URIEncoding="UTF-8"/>
Listener
Şöyle yaparız.
<Listener className="org.apache.catalina.core.AprLifecycleListener"
 SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"
/>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
Realm
Şöyle yaparız. Authentication  (doğrulama) için userBase, userSubtree, userSearch yeterli.
<Realm className="org.apache.catalina.realm.JNDIRealm"
  connectionURL="ldap://mycomapny.org:636" 
  userSubtree="true"
  userBase="DC=test,DC=win,DC=user,DC=org" 
  userSearch="(&amp;(sAMAccountName={0})(objectcategory=user))"
  userRoleName="memberOf" 
  roleBase="DC=test,DC=win,DC=user,DC=org" 
  roleName="cn"
  roleSearch="(member={0})" 
  roleSubtree="true" 
  roleNested="true"/>
Şöyle yaparız.
<Realm className="org.apache.catalina.realm.JNDIRealm"
 connectionURL="ldap://stagetest.com:389"
 userPattern="uid={0},OU=entities,O=us.com"
 roleBase="CN=myGroupName,OU=Groups,O=us.com"
 roleName="CN"
 roleSearch="(member={0})" />
Valve
Şöyle yaparız.
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
  prefix="localhost_access_log" suffix=".txt"
  pattern="%h %l %u %t &quot;%r&quot; %s %b" />

@Produces Anotasyonu

Giriş
Bu anotasyon rest çağrısının ne tipten cevap vereceğini belirtir. Bu anotasyonu kullanırken Java'da tanımlı olan sabitler kullanılabilir veya metin olarak ta kullanılabilir. Metin olarak kullanım pek akıllıca değil çünkü yazım hatası olabiliyor.

Şu kod yanlış
@Produces("appplication/json")
Şöyle yaparız.
@Produces("application/json")

Tomcat Servis Olarak Kurulum

Service Olarak Kurulum - Windows
1. Kurmak için     - service.bat install MyTomcat
2. Kaldırmak için - service.bat remove MyTomcat
    komutları ile servis olarak kurulup kaldırılabilir. Servis'in kullandığı JRE'de şöyle değiştirilebilir.

    Örnek
    Servisin hangi binary dosyayı çalıştırdığını bulmak için şöyle yaparız.
    reg query "HKLM\System\CurrentControlSet\Services\Tomcat8" /v "ImagePath"
    Çıktı olarak şunu alırız.
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tomcat8
    ImagePath    REG_EXPAND_SZ    C:\apache-tomcat-8.5.15\bin\tomcat8.exe
    Service Olarak Kurulum - Linux
    apt-get ile kurulur
    aptitute
    Şöyle yaparız.
    aptitude install tomcat8
    Kurulum sonunda uygulama şu dizindedir.
    /usr/share/tomcat8
    Diğer tüm ayar dosyaları ise şu dizindedir.
    /var/lib/tomcat8
    1. Başlatmak için şöyle yaparız.
    sudo service tomcat7 start
    Servisin kullandığı hesap ismi ve grubu şu dosyadadır.
    /etc/default/tomcat7

    Dosyanın için şöyledir.
    # Run Tomcat as this user ID. Not setting this or leaving it blank will use the
    # default of tomcat7.
    TOMCAT7_USER=tomcat7
    
    # Run Tomcat as this group ID. Not setting this or leaving it blank will use
    # the default of tomcat7.
    TOMCAT7_GROUP=tomcat7


    Duration Sınıfı

    Giriş
    Period'dan farklı olarak artık yıl, yaz saati gibi şeyleri hesaba katmaz. LocalTime gibi 23:59:59 sınıfı yoktur. Daha uzun süreleri de saklayabilir. LocalTime ile arasındaki en önemli farklı açıklayan cümle şöyle
    LocalDateTime is a Temporal and these represent a point in time, not a duration.

    Although "1:30:00" can be interpreted as a point and as a duration, the semantics are different.
    * As a point in time: "Half past one in the morning"
    * As a duration: "An hour and a half"

    One reason this is important is that "25:30:02" is a valid duration, but not a valid time-of-day.

    between metodu
    Örnek 1
    Şöyle yaparız.
    Temporal startInclusive = ...;
    Temporal endExclusive = ...;
    Duration duration = Duration.between(startInclusive, endExclusive);
    Örnek 2
    Elimizde iki Instant olsun.
    Instant start = ...;
    Instant stop = ...;
    Şöyle yaparız.
    Duration d = Duration.between (start,stop);
    getSeconds metodu
    Şöyle yaparız.
    int seconds = duration.getSeconds();
    minus metodu
    Şöyle yaparız.
    Duration diff = duration.minus(duration2);
    of metodu
    Şöyle yaparız.
    ChronoUnit unit = ...;
    Duration duration = Duration.of(1, unit).toNanos();
    ofHours metodu
    Şöyle yaparız.
    Duration compared = Duration.ofHours(8);
    parse metodu
    Format P ile başlar. T time başladığını gösterir. h saati gösterir.
    Örnek
    Şu girdi yanlış olduğu için parse edilemez.
    "PT10HMS";
    Doğru girdi şöyle olmalı
    "PT10H0M0S";
    Örnek
    Şöyle yaparız.
    Duration duration = Duration.parse("PT8h");//8 saat
    Örnek
    Şöyle yaparız.
    //convert first to a valid Duration representation
    String durationStr = input.replaceAll("(\\d+):(\\d+):(\\d+)", "PT$1H$2M$3S");
    Duration duration = Duration.parse(durationStr);
    int seconds = duration.getSeconds();
    plus metodu
    Şöyle yaparız.
    Duration duration = ...;
    Duration duration2 = duration.plus(Duration.ofMinutes(30));
    plusMinutes metodu
    Şöyle yaparız.
    String[] parts = durationAsString.split(":");
    Duration duration = Duration
        .ofHours(1)
        .plusMinutes(2)
        .plusSeconds(3);
    toNanos metodu
    Şöyle yaparız.
    Duration duration = ...;
    long conversion = duration.toNanos();