SIGINT 라고 가끔 본 적이 있을 것이다.
이 것은 Interrupt 시그널을 의미한다.
Interrupt (^c) 시그널은 2
Quit (^\) 시그널은 3
EOF(or Exit ^D) 시그널은 1
이 중에서 2,3번 시그널이 shell script가 도는 동안에 동작안하게 하고 싶으면..
trap "" 2 3 <- 이렇게 무시를 걸어 놓으면 된다.
trap 2 3 reset <-shell script종료 후에는
SIGINT 라고 가끔 본 적이 있을 것이다.
이 것은 Interrupt 시그널을 의미한다.
Interrupt (^c) 시그널은 2
Quit (^\) 시그널은 3
EOF(or Exit ^D) 시그널은 1
이 중에서 2,3번 시그널이 shell script가 도는 동안에 동작안하게 하고 싶으면..
trap "" 2 3 <- 이렇게 무시를 걸어 놓으면 된다.
trap 2 3 reset <-shell script종료 후에는
Linux c개발시 shm 사용방법.
shmget : malloc 처럼 공유메모리 생성
shmat : 생성된 공유메모리를 해당 프로세서로 가져옴(첨부-attach)
shmdt : 가져온 메모리를 다시 반납. (분리-detach )
Linux를 하다보면, 터미널로 접속해서 프로세스를 실행시키고,
나중에 다시 접속해보면.. 죽어있는 경우가 있다.
- 백그라운드로 실행해도 그러하다..
( 백그라운드 실행은 명령어 뒤에 & 추가=> $shell.sh & )
이럴경우
1. nohup으로 실행 : $nohup shell.sh &
2. screen명령어로 실행.(화면까지 보존)
-------screen 사용법--------------
screen -S 스크린네임.
ctrl+a=>c생성
ctrl+a=>shift+a타이틀변경
ctrl+a=>shift+" 리스트
선택
ctrl+a=>c화면 클리어
ctrl+a=>d 나가기(리스트는 있고, 모드만 종료)
screen -r 모드진입(리스트 출력)
ctrl+a=>shift+" 리스트
ctrl+a=>shift+k 리스트선택 종료.
ctrl+a=>Shift+s 화면 분활 화면
ctrl+a=>tab 으로 화면 이동
ctrl+a=>shift+q 종료
ctr
volatile 키워드는 멀티thread시에 도움이 된다.
1. 읽고 쓰기에 대한 원자성. ( byte단위의 원자화는 보장함. alignment는 맞춰줌. )
2. 컴파일러의 임의 리오더링을 방지.
반면,
synchronized는 블록으로 묶인 부분 혹은 변수를 원자화(makes atomic ) 함.
<Wikipedia singleTon 예제>
public class SingletonDemo {
private static volatile SingletonDemo instance = null;
private SingletonDemo() { }
public static SingletonDemo getInstance() {
if (instance == null) {
synchronized (SingletonDemo.class){
if (instance == null) {
instance = new SingletonDemo();
}
}
}
return instance;
}
}
TDD : Test Driven Development
=> 웹 자동화 테스트툴- Sellinium.
BDD: Behavior Driven Development
=> Cucumber.
멀티코어 linux에서 코어를 할당하는 방법:
taskset -pc
{해당 process를 기동할 core 번호} process-pid
예) taskset -pc 0
{process-pid}
만약 cloud상의 VM상에서
이와 같이 특정 core에 할당한 후에는 해당 VM을 reboot하여야 하며,
isolcpus 옵션이 grub.conf 파일에 추가되어서 VM이 생성되어야 한다.
<grub.conf>
# grub.conf generated by anaconda
#
# Note that you do not have to rerun
grub after making changes to this file
# NOTICE: You have a /boot
partition. This means that
# all kernel and initrd paths are
relative to /boot/, eg.
# root (hd0,0)
# kernel
/vmlinuz-version ro root=/dev/mapper/VolGroup-lv_root
# initrd
/initrd-[generic-]version.img
#boot=/dev/xvda
default=1
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title
CentOS (2.6.32-431.3.1.el6.x86_64)
root (hd0,0)
kernel
/vmlinuz-2.6.32-431.3.1.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root
rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD console=hvc0 KEYTABLE=us
rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto
rd_LVM_LV=VolGroup/lv_root rd_NO_DM rhgb quiet isolcpus=0
initrd
/initramfs-2.6.32-431.3.1.el6.x86_64.img
title CentOS
(2.6.32-358.14.1.el6.x86_64)
root (hd0,0)
kernel
/vmlinuz-2.6.32-358.14.1.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root
rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD console=hvc0 KEYTABLE=us
rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto
rd_LVM_LV=VolGroup/lv_root rd_NO_DM rhgb quiet isolcpus=0
initrd
/initramfs-2.6.32-358.14.1.el6.x86_64.img
title CentOS
(2.6.32-279.2.1.el6.x86_64)
root (hd0,0)
kernel
/vmlinuz-2.6.32-279.2.1.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root
rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD console=hvc0 KEYTABLE=us
rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto
rd_LVM_LV=VolGroup/lv_root rd_NO_DM rhgb quiet isolcpus=0
initrd
/initramfs-2.6.32-279.2.1.el6.x86_64.img
title CentOS
(2.6.32-279.el6.x86_64)
root (hd0,0)
kernel
/vmlinuz-2.6.32-279.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS
LANG=en_US.UTF-8 rd_NO_MD console=hvc0 KEYTABLE=us rd_LVM_LV=VolGroup/lv_swap
SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root rd_NO_DM
rhgb quiet isolcpus=0
initrd
/initramfs-2.6.32-279.el6.x86_64.img
-F_ 없어도 됨(2210)
echo ${JOB_NAME} | awk -F_ '{print $3}' |xargs -I {} rm -rf /tmp/doxygen/{};
수많은 프로세스들 한방에 죽이기
ps -ef | grep 키워드 | awk '{print $2}' | xargs -I {} sudo kill {}
find . -name "*.js" -print | xargs grep -n keywordToFind
(filename) (linenumber)
$mongo 해서 client접속하면..
>show tables
//이 중에서 heart category(테이블)을
// user:"kim", pic:1, heart:20, date:'20140303' 이러한 테이블(category)로 가정. (_id는 자동 삽입됨. _class도 간혹 자동삽입-코드일경우)
> db.heart.find() -> 전체 record list.
> db.heart.find().sort( {pic:1} ) -> 전체 리스트를 pic필드로 asending 소팅.
> db.heart.find().limit(2) -> 리스트 중 2개만 출력.
= db.heart.aggregate({ $limit:2 })
> db.heart.distinct("user") -> [ "kim", "lee" ]
> db.heart.distinct("user").length -> 2
> db.heart.aggregate({ $group:{_id:"$pic"} }) -> pic필드를 기준으로 그루핑. ({ => ([{ 이렇게 대괄호 추가가능.(이전버전인듯)
> db.heart.aggregate({ $group:{ _id:"$pic", heartSum:{$sum:"$heart"} } }) -> 각 그룹별로 heartSum산출.
-->복합 aggregate
> db.heart.aggregate(
{$group:{ _id:"$pic", heartSum:{$sum:"$heart"} }},
{$sort:{"hearts":1}},
{$limit:2}
)
//일반적인 Query .
db.inventory.find( { type: 'food', price: { $lt: 9.95 } } )
//aggregate에 Query 추가.
db.heart.aggregate(
bla.. bla.. ,
{ $match : { score : { $gt : 70, $lte : 90 } } }
)
///////spring-data-mongo에서 적용시에는
AggregationOperation match = Aggregation.match(Criteria.where("service").is("EFT").and("source").is("MARKUP"));
AggregationOperation group = Aggregation.group("card_acceptor").and("amount_sum").sum("amount").and("tran_count").count();
Aggregation aggregation = newAggregation(match, group);
AggregationResults<StoreSummary> result = this.mongoTemplate.aggregate(aggregation, "eft_transactions", StoreSummary.class);
<설치 후, 첫 실행. >
sudo /usr/local/hadoop-2.5.0/sbin/start-dfs.sh
<상태 check>
$hdfs dfsadmin -report
<웹브라우저에서 확인.>
http://localhost:50070/
<HDFS 명령어>
$hdfs dfs -ls /
$hdfs dfs -mkdir /myTest
$hdfs dfs -put test.txt /
<Hadoop 명령어>
$hadoop fs -mkdir /wordCount
$hadoop fs -copyFromLocal wordCount.jar /wordCount
$hadoop fs -ls
$hadoop jar wordCount.jar wordCount[main class] /wordCount[folder] /wordCount/output [out folder]
openssh-server를 설치하려고 하니..
openssh-server : Depends: openssh-client (= 1:6.6p1-2ubuntu1) 이런 에러가 뜬다.
이런 경우 다음방식으로 client를 먼저 설치하면 된다.
sudo apt-get install openssh-client=1:6.6p1-2ubuntu1
그외 sudo apt-get 명령어는
sudo apt-get --reinstall install xx
sudo apt-get remove xx
설치된 놈 조회
/var/cache/apt/archives 여기서 ls로 검색. ?
안될때는.. 그냥 sudo apt-cache search blabla 로...하면 됨.
java여러개 깔아서 하나 선택시에는
sudo update-alternatives --config java
sudo update-alternatives --config javac 이렇게 2번.
<서버에서 조회>
sudo apt-cache search xx
sudo apt-cache show xx
(apt-get 이 잘 안될때는)
sudjo apt-get dist-upgrade : 서버목록 업그레이드
sudo apt-get update : 목록 index update.
.deb 파일을 받아서 직접 설치하는 경우는
sudo dpkg -i *.deb 로 하면된다. 참고: http://egloos.zum.com/mcchae/v/10795420
<CentOS>에서는
일반적으로는 $yum install blabla로 하면된다.
rpm패키지 파일을 구했을때는 아래와 같이 한다.
rpm -qa | grep xx 정보조회
rpm -ivh xx.rpm 설치
rpm -e xx 제거
Hadoop : MapReduce과 parallelDB의 장점을 모두 지님.
(DB가 스키마onWrite이라면, 하둡은 스키마onRead 이다)
: write-Once,
read-many, noUpdate-but-Append임.
: 디폴트는 3개의 replica.(다른 racki들) - client는 가까운데서 읽음.
: metaData
(NameNode=Master라고 부르며- single관리되므로 중요..) 는 모두 in-Memory.
: dataNode=Slave(들도 각자의 metaData을 보관함.)
-디폴트 128Mega block들로 구성
- CRC32체크로 분산데이타체크함.
- 512byte단위로 checksum관리해서 매번 체크함
?secodary Name Node는?
- Map & Reduce utubeREF - 카드로설명
: Map-데이터가 있는 곳으로 프로그램이 가서 동작하는 개념.
: Reduce-계산이 끝나면 다시 분리 함.
youtube소개 REF: 25petaByte까지 저장가능, 4500개 머신까지 동작가능.
Pig - 컴파일러
Hive - SQL유사 I/F
HBase - top level apache project - 메신저 메세지는 object형태로 저장가능
HCatalog - 메타data서버 (Hive에서 분리되어 나옴)
기타) Mahout - 머신 러닝 libray for MapReduce
Ambari, Galnglia, Nagios - cluster분석 툴
Sqoop - RDB와 I/F 툴
Cascading - 트랜스레이팅 툴 for Pig..?
Oozie - 스케줄러. workflow 코디네이션.. 언제 실행할지 등.
Flume - 스트리밍 input for Hadoop
Protobuf, Avro, Thrift 를 지원.
Fuse-DFS : os 레벨 access지원.
가상화는 반가상화(para virtualization)과 전가상화(HVM)으로 나뉜다.
(추가적으로 type1:native,bare-metal 방식과 type2:hosted로 나누기도 하는데,
hostOS가 필요없는 type1: Xen, hostOS가 필요한 type2: KVM 이다 : REF-NEW REF-SITE )
cloudStack + Xen으로 대표되는 반가상화 방식이 우수했으나, 내가 느낀 약간의 단점은
단점1. Xen의 네트웍 delay,
단점2. fork시 시간지연
최근 openstack + KVM의 전가상화가 이것을 극복하는 모습니다.
원래는 전가상화가 Mgmt에서 HW와 guestOS간의 바틀넥이 될 수 있으나,
KVM은 linux자체를 변형해서 만든 hypervisor인 만큼 이 문제가 적어 보인다.
openstack + KVM구성도:
(여기서 VM process는 QEMU 위에 올라가게 된다)
단말이 IMS 시스템에서 서버에 등록을 하는 절차.
(VoLTE 통화를 위해서, 단말과 서버간의 사전 절차이다.
VoLTE는 데이타망과 유사한 통화전용LTE망 위에서 통화를 하는 것이므로, VoIP라고 볼 수도 있고,
기존의 CS망에서 통화하던게 발전한 것이므로 일반통화라고 볼 수도 있을 것 같은데..
아무래도 기본 통화로 상용되다 보니 VoIP라고 잘 부르진 않는다. )
1. 단말이 서버로 ID를 보낸다 (First Regi, integrity_protected필드=no)
2. 서버(CSCF)에서 401 unAuthorized 응답을 보낸다
3. 단말이 401응답속의 nonce(challenge)필드 값을 이용해서 도전과제를 풀어서 올린다. (Second Regi, integrity_protected필드=yes)
4. 서버(CSCF)에서 200OK를 보낸다.
이 중에서 3번 항목을 살펴보면
단말의 SIM에는 PUID(고유ID: From필드에 사용), PRID(인증용 ID: userName 필드에사용) 및 key, ck(암호키), ik(변조체크 키) 가 있는데
3번의 과정에서는 ck,ik,nonce+ 이것들을 이용해서 계산된 결과가 올라간다.
서버는 이 결과가 원하는 답이 맞을 경우 Regi를 해 주게 된다.
<인증 방식>
인증 방식에는 aka인증과 md5 인증이 있는데
요즘 단말들이 aka인지 md5인지를 결정하여 올려주는 관계로, 차이만 본다면
aka: 위에 언급한 것처럼 sim을 이용해서 인증. nonce이용
md5: 좀 더 간단한 인증으로 nonce가 아니고 n-nonce 필드를 이용.
javascript에서의 상속은 일반적인 OO와 다르다.
그 이유는 javascript가 OO 언어가 아니고, 함수(prototype)기반 언어라서 그러하다.
대신, prototype과 prototype.constructor를 치환하는 방법으로 상속이 구현 가능하다.
<<예제>>
function AjaxBasic(){
if ( window.XMLHttpRequest){
this.xhr = new XMLHttpRequest();
}else{
console.log("NO XHR support maybe ~ IE6");
return;
}
this.xhr.onreadystatechange=function(){
if (ajaxObj.xhr.readyState==4 && ajaxObj.xhr.status==200)
document.body.innerHTML=ajaxObj.xhr.responseText;
}
//// method.. run()
this.run = function(){
this.xhr.open("GET", "test_data.txt", true);
this.xhr.send();
}
}
function MyAjax(){
this.run = function(fileUrl){
ajaxObj.xhr.open("GET", fileUrl, true);
ajaxObj.xhr.send();
}
}
///Inherit = prototype + constructor
MyAjax.prototype = new AjaxBasic();
MyAjax.prototype.constructor = MyAjax();
간단한 ajax .
function makeRequest(url)
{
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true); //true is A of Ajax=Async
xhr.onreadystatechange = receiveResponse;
xhr.send();
}
function receiveResponse(e)
{
if (this.readyState == 4) //4:complete
{
if (this.status == 200) //200 ok
{
var response = this.responseXML;
...
}
}
}
웹페이지 버튼 콜백 ajax ( JQuery 경우) - 아래에서 CDATA는 없어도 됨.
<script type="text/javascript" th:inline="javascript">
/*<![CDATA[*/
$(function () {
$('.clear-cache').click(function () {
$.ajax({
type: "POST",
url: "/api/internal/v1/clear_cache/banner",
success: function () {
$('#clearCacheModal').modal('show');
}
});
});
});
/*]]>*/
</script>
ForkJoinPool 과 ThreadPoolExecutor 이 대표적으로 ExecutorService를 구현한 class 이다.
Executor<-ExecutorService관계이며, Excutor가 Runnable를 실행하고, ExecutorService 에서 shutdown등으로 관리가능.
(이렇게 Factory 형태로도 많이 쓰인다)
ExecutorService pool = Executors(유틸).newFixedThreadPool (thread num) returns ExecutorSerivce.
=> newFixedThreadPool을 이용한 서버소켓 accept 예제.
pool.execute ( request ); //Executor REF
pool.shutdown() or submit() or blabla; //ExecutorService
==> 참고2 사이트: pool.submit (Callable )으로 실행되지만, 실제 Callable.call이 언제실행될지 모르므로
Executor은 Future를 리턴. future . get() : (blocking임)으로 값가져 옴.
=============ForkJoin Pool==========
ForkJoinPool에 RecursiveAction구현 객체를 invoke 하면
객체의 compute 함수가 실행되면서
compute 내에 구현된 InvokeAll(work1,work2)를 통해 멀티코어를 실행하게 된다.
<<< Factorial을 이용한 ForkJoinPool 예제 >>
public class TestPool {
public static void main(String[] args){
ForkJoinPool pool = new ForkJoinPool();
long time1 = System.currentTimeMillis();
for(int i=0; i<500000;i++){
MyWork myWork = new MyWork(25); //25factorial
pool.invoke(myWork);
}
long time2 = System.currentTimeMillis();
System.out.println("Elapse:" + (time2-time1));
}
}
class MyWork extends RecursiveAction{
int base=0;
int to=1;
long result=1;
//factorial
public MyWork(int base){
this.base = base;
}
//half factorial
public MyWork(int base, int to){
this.base = base;
this.to = to;
}
@Override
protected void compute() {
//////small value Calculate and return
if ( base-to <= 2 ){
System.out.println("END: base,to:" + base +","+to);
for ( int i=base; i >= to; i-- )
result = result*i;
return;
}
//////large value DIVIDE as 2 works.///////////////
int median = to+ (base-to)/2;
MyWork w1 = new MyWork(base, median+1);
MyWork w2 = new MyWork(median, to);
invokeAll( w1, w2); //waiting.... then why USE RecursiveTask(which resturns VALUE)
result = w1.result * w2.result;
System.out.println("FINAL RESULT:" + result);
}
}
<JDK 1.4>
(Selectable)Channel
has
Selector
has
SelectionKey 인데 Selector를 서버채널과 클라이언트 채널에 동시에 등록해 accept와 read동시 수행 가능.
<JDK1.6 >의
java.nio.channels.SelectorProvider 는 linux시스템의 epoll을 구현. select=O(n), epoll=O(1)
nio = non-blocking io 임.
=========Selector 예제===== 서버 thread=====
//nio version
public void run(){
ServerSocketChannel ssc=null;
try{
//for SSC
InetSocketAddress addr = new InetSocketAddress(1990);
ssc = ServerSocketChannel.open();
ssc.socket().bind(addr);
//for Selector
Selector selector=Selector.open();
ssc.configureBlocking(false); //make nonBlocking accept()
ssc.register(selector, SelectionKey.OP_ACCEPT);
while (true){ //select for accept While
int numKeys = selector.select(); //select is non Blocking.
if (numKeys > 0){
//System.out.print(" numKeys:" + numKeys); //too much call
Set<SelectionKey> keySet = selector.selectedKeys(); /// Must be selectedKeys.
Iterator<SelectionKey> it = keySet.iterator();
while( it.hasNext()) {
SelectionKey key = it.next();
if( (key.readyOps() & SelectionKey.OP_ACCEPT)==SelectionKey.OP_ACCEPT){
SocketChannel csc = ((ServerSocketChannel) key.channel()).accept();
csc.configureBlocking(false);
System.out.println(" [Server] Client Connected ------"+csc);
//read Key register
csc.register(selector, SelectionKey.OP_READ);
it.remove();//delete key
}else if( (key.readyOps() & SelectionKey.OP_READ)==SelectionKey.OP_READ){
SocketChannel csc = (SocketChannel) key.channel();
//System.out.println(" [Server] Client READ Event ------"+csc);
readFromClient(csc);
it.remove();//delete key
}
}
}
Thread.sleep(10);
} //while
}catch (Exception e){
e.printStackTrace();
}finally{
try{
if(ssc!=null) ssc.close();
}catch (IOException e){}
}
}//run
Generics: - casting으로부터의 해방.
List<String>,
List<?> ?: any type extends Object
Class<?> : (Object).getClass()로 리턴되는 특정 class의 정보 집합.
JMX도 추가. (JMX등 JEE 참고사이트 )
java.util.Concurrent
- Executor가 대표적: 멀티코어 활용.
그러나, 일반적인 thread프로그래밍 만으로도 (green thread = single thread OS)가
아닌 이상은 멀티코어가 어느정도 적용된다고 함.
그 외
http://skycris.tistory.com/3 1.5에 추가된
boxing/unboxing, - int(원시 형)과 Integer간 자동 형변환.
static import,
annotation 설명
레퍼런스: http://javacan.tistory.com/tag/nio
속도가 향상된 nio(new io)는 기존 java라기 보단 c코드라고 봐야할 것 같다.
DirectBuffer가 속도가 빠르고, IndirectBuffer는 임시용.
Buffer는 보통 Channel(c언어로 된 Stream이라고 보면 될듯) 과 함께 써야 함.
ByteBuffer buf = ByteBuffer.allocateDirect(8);
buf.putByte( (byte)0xAB );
buf.putShort( (short)0xCDEF );
이렇게 하면, buf에 position=3, limit=8=capacity 이 됨.
buf.rewind : p=0.
buf.clear() : p=0, l=8 (초기상태)
buf.flip() : p=0, limit=3(현재위치)
뭔가 write한 후에는 남은 byte를 맨 앞으로 옮겨주는
buf.compact() 필요. 주로 buf.isRemaining()과 함께 쓰이는 듯.
<<실제 예제>>
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try {
FileIntputStream is = new FileInputStream(source);
FileOutputStream out = new FileOutputStream(dest);
inputChannel = is.getChannel();
outputChannel = out.getChannel();
} catch(IOException ex) {
ByteBuffer buffer = ByteBuffer.allocateDirect(512);
int len ;
while ( (len = inputChannel.read(buffer)) != -1) {
buffer.flip(); //뒤쪽 limit을 마킹. 즉 limit=position, position=0이 됨
outputChannel.write(buffer); //읽은거 그대로 write.
buffer.clear(); //p=0, limit=512가 됨.
}
<<짧은 파일을 RandomAccess -> MappedByteBuffer (Direct임) 로 매핑해서.. 파일의 내용을 꺼꾸로 하기..>>
RandomAccessFile ra = new RandomAccessFile("/hello.txt","rw");
FileChannel fc = ra.getChannel();
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE,0, ra.length());
int len = ra.length();
RandomAccessFile ra = new RandomAccessFile("/hello.txt","rw");
FileChannel fc = ra.getChannel();
//파일을 파일 채널을 이용하여 버퍼에 매핑 합니다.
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE,0, ra.length());
int len2 = (int)ra.length();
//파일 자체 내용을 뒤집기
for (int i = 0, j = len2 - 1; i < j; i++, j--)
{
byte b = mbb.get(i);
mbb.put(i, mbb.get(j)); //파일의 내용을 순서 바꿉니다.
mbb.put(j, b);
}
fc.close();
pom.xml을 이용해서 직접 run하는 command:
컴파일 + 실행:
mvn compile exec:java -Dexec.mainClass=com.mongodb.SparkHomework
?아래는 jetty 실행.
mvn clean jetty:run
/etc/init.d/tomcat7 start
/etc/init.d/tomcat7 stop
/etc/init.d/tomcat7 restart
booting시에 자동으로 시작하는 기능은
$ sudo update-rc.d tomcat(7) defaults
제외는
$ sudo update-rc.d -f tomcat(7) remove
라고 입력합니다.
CentOS는 여기 참조: Ref-Site
[Redhat계열] Linux hostname변경
$ hostname : 이건 그냥 조회
$ hostname abc_server : 이렇게 세팅가능하며, 리부팅이 되면 원복이 되는 문제점 존재.
리부팅 시에도 적용되게 하려면
/etc/sysconfig/network 여기서
HOSTNAME=abc_server 이렇게 수정하도록 한다.
ftp에 접속해서 파일을 다 가져오는 shell script는 다음과 같다.
여기서 EOF 대신에 ENDFILE등 다른 임의의 단어를 사용해도 된다.
< autoFTP.sh 내용>
ftp -n 127.0.0.1 << EOF
user root pass1234
cd ftpserver
prompt off
binary
mget *.out
bye
EOF
흔히 보는 linux의 파일권한 type은 다음과 같다.
-rwsrwsrwt
1. 여기서 현재 '-'로 표시되어 있는
첫 글자가 c/b인 경우라면 device file을 뜻한다.
(모두 나열하면)
c: 캐릭터 입출력하는 device
b: 블록 단위로 입출력하는 device
p: named pipe
s: socket
D: door
2. 그리고
네번째, 일곱번째 글자가 s일경우 set-uid 또는 set-gid 비트임.
돌리는 동안 잠깐 super (root)가 된다. ps로 확인 가능
(/usr/bin/passwd 참고. ) 보안체크시 필수체크항목
3. 마지막 글자가
t:sticky 폴더는 타인이 못지우게 함 /tmp/ 용
0. 추가적으로 옵션설정방법:
chmod 에 6777 옵션을 줄 수 있는데
처음 6표시된 자리는
4: set-uid
2: set-gid
1: sticky
과 같은 용도로 사용한다.
Linux 및 unix에서는 파일이
[File명: inode번지] 로 관리가 된다. (ls –i 하면 inode 조회 가능하다)
여기서 inode번지는
è <inode table 구조> 를 참조하게 된다: (ls –l하면 나오는 정보들이라고 보면 된다)
1File Type
2Permission
3Hard Link Count (inode 번지 복사) 하드링크시 사용. ( 용법: ln f1 f2 이며 그 후에 : rm f1 해도 됨. )
단, 파티션이 다르면 번지중복으로 사용 불가
4Owner
5Group
6Size
7Time
8Point à data block저장소를 가르킴
symbolic link의 경우 point에 원본위치 있음 (ln -s f1 f2 로 지정)
Symbolic link장점: 1. 디렉토리도 된다,
2. 파티션 달라도 된다.
solaris에서는 하드링크를 주로 사용하고
linux에서는 심볼릭 링크(소프트 링크)를 주로 사용하게 된다.
LINUX RUN LEVEL
<부팅 순서>
Run-level
0 linux:halt solaris: PROM모드
1 Single모드
2 Multi user 모드 (약간 제외 – NFS, samba제외)
3 Multi user 모드 – 모든서비스 가동
4 X
5. GUI까지 구동( linux에만 존재)
/etc/init.d/ 원본script가 있는데
/etc/rc1.d/kxxx sxxxx 로 링크 함.
( rc1=runLevel K=stop, S=Start 프로세서 )
rc2, rc3….여러 링크 폴더 존재
run_level 스테이징 순서대로 구동 됨.
linux 커널을 빌드해서 설치하다 보니
/etc가 read-Only인 경우가 발생했다.
=> (원인은 cloud다 보니, XenServer 에서 발생.. /var/log/messages에 blkfront: barrier: empty write xvdb op failed )
확인:
$ cat /proc/mounts 해보면
/dev/xvda3 / ext3 ro,relatime,errors=continue,user_xattr,acl,barrier=1,data=ordered 0 0
이렇게 ro가 보인다.
$cat /etc/fstab 해보면 부팅시 mount되는 type /위치를 알 수 있다.
이 때 remount를 하면 되는데
$ mount -o rw,remount -t ext3 /dev/xvda3 /
=> mount: cannot remount block device /dev/xvda3 read-write, is write-protected
또 에러가 난다.
제대로 된 remount를 하려면
/etc/fstab 에다가 옵션이 defaults일 경우 ext3 rw,relatime,errors=continue,user_xattr,acl,barrier=1,data=ordered 라고 가정하고
옵션을 defaults ==> ext3 rw,relatime,errors=continue,user_xattr,acl,barrier=0,data=ordered 으로 수정해서 한번 해본다.
기존에는 chkconfig이란 명령어로 init.d 데몬들을 관리했지만
ubuntu 14.04부터는
update-rc.d 명령어로 하게 되었다.
만약 tomcat7을 startup시에 실행하고 싶지 않다면
$ update-rc.d -f tomcat7 remove
로 하면된다.
Linux 커널 빌드
소스를 받은 후에
1) $ uname -r 해서 현재 linux 커널 버전 확인
2.6.32-281-blabla.
2) 필요시에만.. 즉 재빌드 하는 경우 등에 이전 빌드 clean해 놓기
$make clean && make mrproper
3) 현재 config을 .config로 복사
cp /boot/config-2.6.32-281-blabla ./.config
4)
$make menuconfig 해서 GUI화면이 뜨게 되면 그냥 exit하면서 save=Yes 로 답하면 됨.
5)
$make all (혹은 make -j4 all : 4 core cpu일 경우 4배 빨리 build)
6)혹은 rpm으로 build하기 위해서는 rpm-build 툴이 깔려있어야 한다. 그 후에 ( 예)yum install rpm-build )
$make rpm
해당 rpm을 설치시에는
$rpm -ivh kernel-x.x.xxblabla.rpm 하면 됨.
<개인적인 firmware conflict발생 및 conflict해결>
$yum list kernel kernel-firmware
$yum remove kernel kernel-firmware.noarch 까지 해서 해결.
<설치 완료후 grub설정 을 하려는데..>
1. initramfs파일이 /boot에 없어서
$dracut initramfs-2.6.39.4.img 2.6.39.4
2. /boot/grub/grub.conf 수정.
- 0번자리(즉 윗자리)에 4줄 복사해서 추가하고 vmlnuz-버전과 initramfs 버전 수정.
Linux에서 네트웍 진단이나 통계시에
netstat 커맨드가 매우 유용하게 쓰인다.
netstat에는 여러가지 옵션이 존재하는데, 이 중에서 비교적 많이 쓰게 되는 옵션은 다음과 같다.
- netstat -nap (n:숫자로 표시, a:all, p:프로세스 ID) : 즉 프로세서별로 통계
- netstat -ntl (tcp 리스닝), -nul (udp 리스닝) : tcp/udp 리스닝 상태
- netstat -su (s:통계, u=udp) : udp통계
그 외에 nmap이라는 유틸리티를 설치할 경우 특정 IP에 대한 상대방 진단이 가능한데
사용법은
- nmap -sU -p 100-2000 +상대ip (s:스캔, U=UDP -p: 포트대역)