2023.08 Chrome 한글 전환 이슈 등등 이슈

Google Chrome 사이트에서 RPM 다운로드 받지 않고, Fedora Repository에 있는 Chrome 설치하면 아무 문제 없네;;

 

----------------------------------------------------------------

 

2023부터 네이버 웨일로 바꿔 사용 중.. 위 문제들 없이 좋은거 같음

(deb를 rpm으로 변환해서 설치)

 

----------------------------------------------------------------

 

36 버전 사용 중 업데이트 시 또는 37 버전 에서 Chrome 렌더링 이슈 생김.. 깜빡깜빡.. 한 참 뒤에 열리기는 함..

 

열리면 chrome://flags 들어가서 Vulkan Disabled

비디오 하드웨어 디코딩 성능 관련 옵션으로 보임

 

[확인] https://forum.babylonjs.com/t/performance-and-rendering-issues-since-fedora-37-upgrade/35739

 

Performance and rendering issues since Fedora 37 upgrade

I upgraded to Fedora 37 and now all Babylon-related rendering is flickering (with a bright interframe) and the browser seems to be struggling because of high CPU load. Almost any other WebGL(2) content is rendering just as before (e.g. three.js-based). I t

forum.babylonjs.com

Wayland, X11 옵션 선택

chrome://flags/#ozone-platform-hint

 

 

Fedora 31 - cinnamon

PC에 로그인된 원래 세션으로 원격 접속 하기

sudo dnf install xrdp x11vnc

sudo vi /etc/xrdp/xrdp.ini
[Xvnc]
name=Xvnc
lib=libvnc.so
username=ask
password=ask
ip=127.0.0.1
port=5900

sudo vi /usr/lib/systemd/system/x11vnc.service
[Unit]
Description=Start x11vnc at startup.
After=multi-user.target

[Service]
Type=simple
#ExecStart=/usr/sbin/runuser -l ddakker `/usr/bin/x11vnc -auth guess -forever -loop -noxdamage -repeat -rfbauth /home/ddakker/.vnc/passwd -rfbport 5900 -shared`
ExecStart=/usr/bin/x11vnc -auth guess -forever -loop -noxdamage -repeat -rfbauth /home/ddakker/.vnc/passwd -rfbport 5900 -shared

[Install]
WantedBy=multi-user.target

sudo systemctl daemon-reload
sudo systemctl enable x11vnc.service

sudo systemctl enable xrdp.service

윈도우 컴퓨터에서 "원격 데스크톱 연결" 프로그램으로 연결

---------------------------------------------------------------------
  • VNC Server
    • Fedora 24 GUI
      • TightVNC version 1.3.10
  • VNC Viewer
    • Windows 10
      • TigerVNC
Viewer 는 Tiger 이 내 상황에서는 가장 최적인듯.
창 사이즈 늘림/줄임 및 최대화면에 따라 Fedora 해상도가 자동으로 변경


Windows Batch Script 심오하군...


특정 Tomcat Instance 찾아 KILL

@echo off
setlocal enableDelayedExpansion

# Command 에서는...
wmic process where "Name='java.exe' AND commandLine like '%test-app%'" delete

# Batch Script 에서는 "%" 변수에대한 접두사라서 LIKE 검색이 안되니 두개로... 그 안에 변수라면 아래와 같이 
wmic process where "Name='java.exe' AND commandLine like '%%%HTTPD_WORKER_NM%%%'" delete

Tomcat 기동여부 확인 - 해당 포트가 떠 있나 확인 후 있으면 PID 및 실행 문자열 출력

@echo off
setlocal enableDelayedExpansion

netstat -na | find "LISTENING" | find /C ":%AJP_PORT%" > tmpFile
set /P result=<tmpFile
del tmpFile

REM echo !result!
if !result!==0 (
	echo ===== TOMCAT IS STOPED =====
) else (
	echo ===== TOMCAT IS RUNNING =====
	wmic process where "Name='java.exe' AND commandLine like '%%%HTTPD_WORKER_NM%%%'" get commandLine, processid
)


삽질 1. timezone 부분

logstash, elasticsearch(plugis등), kibana 골치 아프니 UTC로 모두 바꾸니 편함...ㅡㅡ;


[logstash]

dd/MMM/yyyy:HH:mm:ss Z 했었는데 처리가 안되서.. 아래와 같이 했더니 해결...

         -> https://discuss.elastic.co/t/how-to-set-timestamp-timezone/28401/10

[kibana]

Settings -> Advanced -> dateFormat:tz -> UTC 선택




[logconf/apache.conf]

input {
  stdin { }
}

filter {
  grok {
    patterns_dir => ["./patterns"]
    # 본인 로그 패턴에 따라 설정
    match => { "message" => "%{COMMONAPACHELOG} %{NUMBER:responseTime} %{ALL_STR:qq1} %{ALL_STR:qq2} %{QS:referrer} %{QS:agent}" }
  }
  date {
    match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss +0900" ]
    timezone => "UTC"
  }
}

output {
  stdout { codec => json }
}


[logconf/apache.conf]

# 파일 단위 -> elasticsearch
input {
  file {
    path => "/usr/local/tomcat/logstash/dump_logs/ssl/*"
    start_position => "beginning"
  }
}

filter {
  grok {
    patterns_dir => ["./patterns"]
    # 본인 로그 패턴에 따라 설정
    match => { "message" => "%{COMMONAPACHELOG} %{ALL_STR:qq1} %{ALL_STR:qq2} %{QS:referrer} %{QS:agent}" }
  }
  date {
    match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss +0900" ]
    timezone => "UTC"
  }
}

output {
  elasticsearch { hosts => ["localhost:9200"]
                  index => "apache-access-log-%{+YYYY-MM-dd}"
                  document_type => "web01"
                }
  #stdout { codec => rubydebug }
}

[haproxy]

input {
  #stdin { }
  file {
    type => "searchWas"
    path => "/usr/local/tomcat/logstash/dump_logs/haproxy/haproxy-searchWas.log*"
    start_position => "beginning"
  }
  file {
    type => "aqmp"
    path => "/usr/local/tomcat/logstash/dump_logs/haproxy/haproxy-aqmp.log*"
    start_position => "beginning"
  }
}

  
filter {
  if [type] == "searchWas" {
    grok {
      patterns_dir => ["./patterns"]
    # 본인 로그 패턴에 따라 설정
      match => { "message" => "%{HAPROXYHTTP}" }
    }
    date {
      match => [ "accept_date", "dd/MMM/YYYY:HH:mm:ss.SSS" ]
      timezone => "UTC"
    }
  } else if [type] == "aqmp" {
    grok {
      patterns_dir => ["./patterns"]
      match => { "message" => "%{HAPROXYTCP}" }
    }
    date {
      match => [ "accept_date", "dd/MMM/YYYY:HH:mm:ss.SSS" ]
      timezone => "UTC"
    }
  }
}

output {
  #stdout { codec => json }
  
  if [type] == "searchWas" {
    elasticsearch {  
      hosts => ["localhost:9200"]
      index => "haproxy-access-log-%{+YYYY-MM-dd}"
      document_type => "searchWas"
    }
  } else if [type] == "aqmp" {
    elasticsearch {  
      hosts => ["localhost:9200"]
      index => "haproxy-access-log-%{+YYYY-MM-dd}"
      document_type => "aqmp"
    }
  }
}

[logconf/test-db.conf] db -> elasticsearch 케이스

input {
        jdbc {
                jdbc_driver_library => "/usr/local/tomcat/logstash/lib/mysql-connector-java-5.1.38.jar"
                jdbc_driver_class => "com.mysql.jdbc.Driver"
                jdbc_connection_string => "jdbc:mysql://mariadb-dev:3306/log"
                jdbc_user => "log"
                jdbc_password => "test"
                statement => "SELECT * FROM ez_apache_access_log_201602"
                #schedule => "* * * * *"
                jdbc_paging_enabled => "true"
                jdbc_page_size => "50000"

        }
}

[patterns/custom.conf]

ALL_STR .*

test exec

$ bin/logstash -f logconf/apache.conf 
192.168.1.100 - - [17/Jul/2016:21:08:51 +0900] "GET /test/list HTTP/1.1" 200 17194 5657 -/- (-%) "http://ddakker.test.com/test/add?test=1" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)"

mappings -> 수동 index/document mapping 생성 예제

$ curl -XPUT http://localhost:9200/log_httpd -d '
{
  "mappings": {
    "web01": {
      "properties": {
        "req_query_string": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "req_dt": {
          "type": "string"
        },
        "referrer_query_string": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "referrer_domain": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "req_ext": {
          "type": "string"
        },
        "referrer_ext": {
          "type": "string"
        },
        "res_status": {
          "type": "string"
        },
        "req_mall_type": {
          "type": "string"
        },
        "@version": {
          "type": "string"
        },
        "ip": {
          "type": "string"
        },
        "req_uri": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "@timestamp": {
          "format": "strict_date_optional_time||epoch_millis",
          "type": "date"
        },
        "referrer_mall_type": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "method": {
          "type": "string"
        },
        "referrer_uri": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    }
  }
}'


외부 mysql 활용

yum install epel-release

yum groupinstall "Development Tools"

yum install openssl-devel readline-devel zlib-devel curl-devel libyaml-devel

yum install httpd httpd-devel

yum install ImageMagick ImageMagick-devel

## ubuntu desktop 에서 할때
# sudo apt-get install apache2 curl bison libbison-dev zlib1g-dev libssl-dev sqlite3 libsqlite3-dev autoconf automake build-essential libtool libreadline6-dev libyaml-dev libxml2-dev libcurl4-openssl-dev libssl-dev libgpg-error-dev autotools-dev imagemagick libmagickcore-dev libmagickwand-dev

wget http://www.ruby-lang.org/ko/downloads/

tar zxvf ruby-2.3.1.tar.gz 
cd ruby-2.3.1
./configure
make
make install

gem install bundler --no-rdoc --no-ri

wget http://www.redmine.org/releases/redmine-3.3.0.tar.gz

tar xvzf redmine-3.3.0.tar.gz

mv redmine-3.0.3 /usr/local/.
ln -s redmine-3.0.3 redmine


cp config/database.yml.example 

vi config/database.yml

bundle install --without development test postgresql sqlite

rake generate_secret_token
RAILS_ENV=production rake db:migrate
RAILS_ENV=production rake redmine:load_default_data

#ruby bin/rails server webrick –e production –b 192.168.1.11
bundle exec rails server webrick -e production
bundle exec rails server webrick -e production --port=40000
bundle exec rails server webrick -e production --binding=192.168.1.11 --port=40000


# thin 서버로 띄우기

gem install thin

vi Gemfile
# 하위 추가
gem "thin"

bundle install --path vendor/bundle

thin start -e production -p 40000 -c /usr/local/redmine --prefix=/redmine
curl http://192.168.1.11:40000/


# context path 바꿔보기

cp config/additional_environment.rb additional_environment.rb.example
vi config/additional_environment.rb
# 하위 추가
config.relative_url_root = '/redmine'


thin start -e production -p 40000 -c /usr/local/redmine --prefix=/redmine
thin start -d -e production -p 40000 -c /usr/local/redmine --prefix=/redmine
curl http://192.168.1.11:40000/redmine

# 기존 웹서버 httpd 에 추가하기

ProxyPass /redmine http://192.168.1.11:40000/redmine

curl http://dev.ddakker.pe.kr/redmine

# 시작/중지/관리
startup.sh
stop.sh
rake_plugin.sh
 
 
# 플러그인 설치
wget https://github.com/peclik/clipboard_image_paste/archive/master.zip
unzip master.zip
mv clipboard_image_paste-master plugins/clipboard_image_paste
 
RAILS_ENV=production rake redmine:plugins    (rake_plugin.sh 만들어 놓음)
 
# 설치된 플러그인
1. 이미지 클립보드 붙여 넣기 - Clipboard image paste
2. 일감 진행현황 그래프 - Progressive Projects List plugin
3. 일감 상황 그래프 - Redmine Graphs plugin
4. 로그인 히스토리 - Redmine Login Audit plugin
5. 일감 작업자별 현황 - Redmine (Monitoring & Controlling | Monitoramento & Controle)
 
 
# 플러그인 삭제
rake redmine:plugins:migrate NAME=플러그임이름 VERSION=0 RAILS_ENV=production
rm -Rf plugins/플러그인이름


Name

addtest

Context

Java type members (Automatically insert Checked)

Pattern

@${testType:newType(org.junit.Test)}
public void test_${name}() {
    ${staticImport:importStatic('org.junit.Assert.*', 'org.hamcrest.Matchers.*')}
}



Name

addlog

Context

Java type members (Automatically insert Checked)

Pattern

private static Logger log = LoggerFactory.getLogger(${enclosing_type}.class);
${imp:import(org.slf4j.Logger, org.slf4j.LoggerFactory)}



Name

addcon

Context

Java type members (Automatically insert Checked)

Pattern

@RequestMapping(value="${uri_name}", method={RequestMethod.GET})
public String ${method_name}(Model model) {
    return "${view_name}";
}
${imp:import(org.springframework.web.bind.annotation.RequestMapping, org.springframework.ui.Model, org.springframework.web.bind.annotation.RequestMethod)}



Name

addspringtest

Context

Java type members (Automatically insert Checked)

Pattern

${imp:import(org.junit.runner.RunWith, org.springframework.test.context.junit4.SpringJUnit4ClassRunner, org.springframework.test.context.ContextConfiguration)}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath*:config/spring/context-common.xml",
        "classpath*:config/spring/context-transaction.xml",
        "classpath*:config/spring/context-datasource.xml"
})${cursor}

Jolokia를 알게되서 최근까지 Servlet Container가 지원되는 부분에서만 이용했었는데 Servlet Container가 지원되지 않는 JVM 기반 Daemon의 MBean 을 모니터링 할 일이 생겨서 봤더니, Jolokia 에  JVM-Agent 있었군..



#!/bin/sh

..
..

PID=`ps -ef | grep java | grep "$DAEMON_NAME " | awk '{print $2}'`
echo " +$PID"

java -jar ...../jolokia-jvm-1.3.1-agent.jar start $PID --port=$MONITOR_PORT --host=$BIND_ADDR


# -- log
# +19102
# Started Jolokia for PID 19102
# http://---:---/jolokia/



Servlet Container 가 지원 될경우에는 WAR-Agent(jolokia-war-x.war) 를 Tomcat 이라면 webapps/ 하위에 복사 하거나 server.xml 에서 Context 부분에 추가 해주면 된다.


WebSocket 관련 개발을 하다가 데이터 송/수신 관련 데이터만 보고 싶다면..


Chrome 웹 스토어에서 "Dark WebSocket Terminal" 를 활용!!




프로세스와는 무관한 작업으로 인한 지연 현상이 발생하여 비동기 방식 처리를 고민하게되었다.


로그 히스토리를 DB에 기록하는 행위들인데 이 부분들에서 INSERT 시 지연이 발생하여 파일로 쌓았다가 긁어가야 하나.. 어떻게해야 하나 고민 하던 중 WAS 에서 제공하는 JMS 를 사용할까 하다가 ActiveMQ, RabbitMQ 를 셈플링 해보았다.


선택은 Cluster, Mirroring 설정이 간편한 RabbitMQ!!


[Cluster] https://www.rabbitmq.com/clustering.html

[Mirroring] https://www.rabbitmq.com/ha.html


그대로 따라 하기만 하면 잘 된다.


[설치]

esl-erlang_17.5-1~centos~6_amd64.rpm

rabbitmq-server-3.5.1-1.noarch.rpm


우선 서버당 /var/lib/rabbitmq/.erlang.cookie 값을 동일 하게 일치 시킨다.


하지만 난 하나의 물리 서버에 MQ서버 NODE 두개씩 올려보았다.


[rabbitmq@dev01]

   - mq11 - /usr/local/mq/domain/mq11

   - mq12 - /usr/local/mq/domain/mq12

[rabbitmq@dev02]

   - mq21 - /usr/local/mq/domain/mq21

   - mq22 - /usr/local/mq/domain/mq21



관리를 편리하게 하기 위해서 NODE 기반 명령어 스크립트를 만들어 둔다.

env.sh 에서 RabbitMQ 포트 번호 및 웹 관리 포트번호를 설정 하게 한다.


각각 디렉토리에 들어가서 각각 start.sh 를 실하면 알아서 뜬다.


env.sh - 기본 동적 설정

#!/bin/sh

NODE_PORT=각각 다르게 포트번호
NODE_MANAGEMENT_PORT=각각 다르게 포트번호(웹 관리 포트)
NODE_NAME=각각 NODE 이름


start.sh - MQ NODE 시작

#!/bin/sh

. ./env.sh


export RABBITMQ_NODE_PORT=$NODE_PORT 
export RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,$NODE_MANAGEMENT_PORT}]"
export RABBITMQ_NODENAME=$NODE_NAME
export RABBITMQ_MNESIA_DIR=/usr/local/mq/domains/$NODE_NAME/mnesia
export RABBITMQ_LOG_BASE=/usr/local/mq/domains/$NODE_NAME/logs
export RABBITMQ_CONFIG_FILE=/usr/local/mq/domains/$NODE_NAME/rabbitmq
/usr/sbin/rabbitmq-server -detached

echo "============================================================="
echo "   RabbitMQ Server 3.5.1-1.noarch           ddakker@gmail.com"
echo "-------------------------------------------------------------"
echo "RABBITMQ_NODENAME=$RABBITMQ_NODENAME"
echo "RABBITMQ_NODE_PORT=$RABBITMQ_NODE_PORT"
echo "NODE_MANAGEMENT_PORT=$NODE_MANAGEMENT_PORT"
echo "RABBITMQ_MNESIA_DIR=$RABBITMQ_MNESIA_DIR"
echo "RABBITMQ_LOG_BASE=$RABBITMQ_LOG_BASE"
echo "RABBITMQ_CONFIG_FILE=$RABBITMQ_CONFIG_FILE.config"
echo "============================================================="


stop.sh - MQ NODE 중지

#!/bin/sh

. ./env.sh

rabbitmqctl -n $NODE_NAME stop


app_start.sh - MQ NODE 관리앱 시작

#!/bin/sh

. ./env.sh

rabbitmqctl -n $NODE_NAME start_app


app_stop.sh - MQ NODE 관리앱 중지

#!/bin/sh

. ./env.sh

rabbitmqctl -n $NODE_NAME stop_app


ctl.sh - rabbitmqctl NODE 옵션 지정한 명령어

#!/bin/sh

. ./env.sh

echo "rabbitmqctl -n $NODE_NAME $1 $2 $3"
rabbitmqctl -n $NODE_NAME $1 $2 $3


status.sh - 상태 정보

#!/bin/sh

. ./env.sh

rabbitmqctl -n $NODE_NAME status
rabbitmqctl -n $NODE_NAME cluster_status


rabbitmq.config - 기본 설정 파일

[
   {mnesia, [{dump_log_write_threshold, 1000}]},
   {rabbit, [
        {log_levels, [{connection, info}]}
   ]},
   {rabbitmq_management, [
       {redirect_old_port, false}
   ]}
].


[NODE 별로 기동]

[rabbitmq@dev01 mq11]$ ./start.sh

[rabbitmq@dev01 mq12]$ ./start.sh

[rabbitmq@dev02 mq21]$ ./start.sh

[rabbitmq@dev02 mq22]$ ./start.sh


[Clustering] - mq11 을 기준으로 한다.(mq11 에서는 안 해도 됨)

[rabbitmq@dev01 mq12]$ ./app_stop.sh

[rabbitmq@dev01 mq12]$ ./ctl.sh join_cluster mq11@dev01

[rabbitmq@dev01 mq12]$ ./app_start.sh



[rabbitmq@dev02 mq21]$ ./app_stop.sh

[rabbitmq@dev02 mq21]$ ./ctl.sh join_cluster mq11@dev01

[rabbitmq@dev02 mq21]$./app_start.sh


[rabbitmq@dev02 mq22]$ ./app_stop.sh

[rabbitmq@dev02 mq22]$ ./ctl.sh join_cluster mq11@dev01

[rabbitmq@dev02 mq22]$ ./app_start.sh


[Mirroring] - Cluster 되면 아무곳에서 해도 됨

./ctl.sh set_policy 사용해도 되고, 그냥 "admin Tab" -> "Policies" 메뉴에서 UI상으로 하는게 편리!!

애래 Node 부분에 "+3" 부분이 보여야 함(정상/비정상 여부에 따라서 복제된 정보가 파랑숫자, 빨강숫자로 표현됨)

장애 후 복구된 서버에 이전데이터 동기(복제) 처리는 하지 않았음




[웹 접속 계정 생성 및 권한 부여] - Cluster 되면 아무곳에서 해도 됨

[rabbitmq@dev01 mq11]$ ./ctl.sh add_user test 1234

[rabbitmq@dev01 mq11]$ ./ctl.sh set_user_tags test administrator

그냥 "admin Tab" -> "Users" 메뉴에서 UI상으로 하는게 편리!!



앞단에 L4 를 붙이면 좋겠음








Slack 라는 업무용 메신저를 회사 동료가 알려줘서 우선 기존 모니터링 SMS 발송 부분을 Slack 으로 부분적으로 대체 해보기로 했다.


JAVA Client API로는 여러가지가 있고, 메시지 발송용으로는 아래 두가지 아무거나 사용하면 될 것 같다.

(https://api.slack.com/community)


SimpleSlackAPI - https://github.com/Ullink/simple-slack-api

SlackSDK - https://github.com/estebanwasinger/slack-sdk


SimpleSlackAPI 의 경우는 본인 계정 Token 기반으로만 글을 남길 수 있고, 내용 이외에 스타일 구조 메시지를 넣을 수 있다.(제목, 들여 쓰기 내용 등)

SlackSDK 의 경우는 본인 계정 Token 기반으로는 인증 하되 전송자명, 전송자 이미지를 수동으로 조정 가능하다.


각각 단순 셈플링시의 차이점이며 자세한 API는 아직 잘 모름!!

하지만 이정도만 해도 현재로서는 충분함!!


[SimpleSlackAPI]

package com.ullink.slack;


import org.junit.Test;

import com.ullink.slack.simpleslackapi.SlackAttachment;
import com.ullink.slack.simpleslackapi.SlackChannel;
import com.ullink.slack.simpleslackapi.SlackSession;
import com.ullink.slack.simpleslackapi.impl.SlackChannelImpl;
import com.ullink.slack.simpleslackapi.impl.SlackSessionFactory;

public class SlasckTest {
	@Test
	public void create() {
		final SlackSession session = SlackSessionFactory.createWebSocketSlackSession("개인 계정 Token 문자열");
		
		SlackChannel channel = new SlackChannelImpl("#cms-batch", null, null, null);
		session.sendMessage(channel, "내용이여", new SlackAttachment("title", "fallback", "text", "pretext"));
	}
}


[SlackSDK]

package msg.test;

import org.junit.Test;
import org.stevew.SlackClient;

public class SlackTest {
	@Test
	public void create1() {
		SlackClient sc = new SlackClient("개인 계정 Token 문자열");
		sc.sendMessage("내용이여", "#channel-name", "전송자명(쓰는대로 됨)", "http://../logo.png");
	}
}



+ Recent posts