вторник, 24 ноября 2009 г.

Информация о Linux машине

Понадобилось мне на днях получить полную информацию о сервере на котором я работал.
Давайте рассмотрим как же это можно сделать.

Информацию о установленном дистрибутиве:
$ cat /etc/*-release

Обладатели Ubuntu увидят нечто подобное следующему:
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=9.10
DISTRIB_CODENAME=karmic
DISTRIB_DESCRIPTION="Ubuntu 9.10"

Информацию о системе можно получить следующей комбинацией команд:
$ cat /proc/version

В Ubuntu:
Linux version 2.6.31-15-generic (buildd@yellow) (gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu8) ) #50-Ubuntu SMP Tue Nov 10 14:53:52 UTC 2009


Так же можно получить немного информации воспользовавшись
$ uname -a

В Ubuntu:
Linux alekseiko 2.6.31-15-generic #50-Ubuntu SMP Tue Nov 10 14:53:52 UTC 2009 x86_64 GNU/Linux

Информацию по объему памяти можно получить
$ cat /proc/meminfo

Информацию по процессору получаем вот так:
$ cat /proc/cpuinfo

Информацию о кол-ве дискового пространства:
$ df -h

Этот список буду продолжать, чтобы самому можно было заглянуть и освежить в памяти то что позабылось :)




Читать далее

четверг, 24 сентября 2009 г.

JSP для определения JAR'ника на сервере по имени класса.

Мал золотник да дорог.
Народная пословица(с)
    Я работаю над очень большим J2EE приложением и частенько сталкиваюсь с проблеммой(и не только я сталкиваюсь но и мои коллеги) определения из какого jar'ника загружен тот или иной класс и где этот jar'ник на сервере лежит.

    Для таких целей я написал давольно таки простенькую, но очень полезную jsp :-) которая принемает на вход имя класса и возвращает, где лижет тот jar'ник из которого загружен необходимый класс. Сама jsp удобна тем что подкладывать её можно на рабочий сервер без перезагрузки. Вообщем получилась некая мини тулза.
    Код её можно посматреть/скопировать здесь getJar.jsp

    Ну это вообщем все что я хотел поведать сегодня. Всем всего хорошего :-)

Читать далее

воскресенье, 19 июля 2009 г.

Работа с memcachedb в JAVA.

Нет причин тормазить свое развитие.
Георгий Александров.
Здравствуйте друзья!!!
В этом посте я бы хотел вам рассказать про возможности использования memcachedb на java.

О memcachedb
Давайте начнем наш разговор с того, что разберемся, что же это за зверь такой memcachedb. В двух словах это такой вид субд, обращение к которой происходит через протокол memcached (интересная презентация на эту тему), а бэкэндом является BerkeleyDB. Более подробно можно прочитать здесь.

Установка и запуск
Ну что ж приступим к установке у себя на компьютере этой прелести. Сразу хочу оговориться, что устанавливать мы будем на Ubuntu, но на других платформах я думаю, никаких сложностей с установкой у вас не возникнет.
Для начала нам нужно установить libevent.
sudo apt-get install libevent1 libevent-dev
Теперь нам необходимо поставить BerkeleyDB. Исходники скачать можно здесь.
tar -xvf db-4.7.25.tar.gz
cd db-4.7.25/build_unix
../dist/configure
make
sudo make install
А вот теперь можно качнуть и поставить memcachedb. Исходники скачать можно здесь.
tar -xvf memcachedb-1.2.0.tar.gz
cd memcachedb-1.2.0
./configure
make
sudo make install
Ну вот мы все установили и теперь можем запустить.
memcachedb -d -v -u root -f some.db -N -H ~/memcachedb
Java клиент
Как я уже говорил ранее, интерфейсом для работы является memcached. Существует несколько клиентов для работы с memcached. Полный список клиентов можно посмотреть здесь. Я выбрал spymemcached, поэтому дальнейшее повествование пойдет о нем.

Demo application
Наконец-то мы все скачали, установили, запустили и подключили. Теперь можем написать небольшое демонстрационное приложение. Наше приложение будет некое подобие тестовой системы. Оно будет задавать пользователю вопрос, ждать пока пользователь ответит на вопрос и сверять правильно ли ответил пользователь на поставленный вопрос. Так как приложение мы пишем для демонстрации работы с memcachedb то, особо сильной логикой перегружать его не будем.
Немного расскажу как у нас будут хранится данные так как memcachedb является бд key=value то мы будем использовать так называемые пространства имен т.е.[namespace]:[key]=[value].
Ну что ж вроде все обговарили, код с комментариями в судию :)
  1. /**
  2. * Copyright (c) 2009 alekseiko alekseiko@gmx.com
  3. */
  4. package memcachedb.example.main;
  5. import java.io.BufferedReader;
  6. import java.io.IOException;
  7. import java.io.InputStreamReader;
  8. import java.net.InetSocketAddress;
  9. import net.spy.memcached.MemcachedClient;
  10. /**
  11. * This is main class for example.
  12. *
  13. * @author alekseiko
  14. *
  15. */
  16. public class Main {
  17. // Customize for memcachedb
  18. private static MemcachedClient client;
  19. private static final String SERVER_NAME = "localhost";
  20. private static final int SERVER_PORT = 21201;
  21. private static final int EXPIRED = 0;
  22. // Memcachedb namespace and key
  23. private static final String TASK_SEQUENCE = "taskSequence";
  24. private static final String TASK_QUESTION = "task_question:";
  25. private static final String TASK_ANSWERS = "task_answers:";
  26. private static final String TASK_TRUE_ANSWER = "task_true_answer:";
  27. // User command
  28. private static final String STOP_COMMAND = "stop";
  29. private static final String NEXT_TASK_COMMAND = "n";
  30. // Splitters
  31. private static final String ANSWER_SPLITTER = ",";
  32. private static final String ANSWER_NUMBER_SPLITTER = ") ";
  33. // Messages
  34. private static final String CONGRATULATION_MESSAGE = "Congratulation! " +
  35. "Enter 'n' for get next question";
  36. private static final String QUESTIONS_IS_COMPLETE_MESSAGE = "Question is" +
  37. " complete.";
  38. private static final String DATA_IS_CORRUPT_MESSAGE = "Data is corrupt.";
  39. private static final String BAD_ANSWER = "Sorry you answer is incorrect. " +
  40. "Try again.";
  41. /**
  42. * General logic for work with memcachedb and user i/o.
  43. *
  44. * @param args
  45. * @throws IOException
  46. */
  47. public static void main(String[] args) throws IOException {
  48. // Connect to memcachedb
  49. client = new MemcachedClient(new InetSocketAddress(SERVER_NAME,
  50. SERVER_PORT));
  51. // Hardcode fill memcachedb of tasks.
  52. fillMemcachedbOfTask();
  53. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  54. String msg = null;
  55. // Default currentTask=0 because task begin with 1
  56. int currentTaskId = 0;
  57. // Get last sequence value
  58. int maxTaskId = (Integer) client.get(TASK_SEQUENCE);
  59. while(!STOP_COMMAND.equals(msg = br.readLine())) {
  60. if (NEXT_TASK_COMMAND.equals(msg)) {
  61. if (currentTaskId >= maxTaskId) {
  62. System.out.println(QUESTIONS_IS_COMPLETE_MESSAGE);
  63. break;
  64. }
  65. currentTaskId++;
  66. // Get task from memcachedb.
  67. String question = (String) client.get(TASK_QUESTION + currentTaskId);
  68. String answers = (String) client.get(TASK_ANSWERS + currentTaskId);
  69. if (question !=null && answers != null) {
  70. // Out question
  71. System.out.println(question);
  72. // Split answers
  73. String[] answerList = answers.split(ANSWER_SPLITTER);
  74. // Out answers
  75. for (int i = 0;i < answerList.length;i++) {
  76. System.out.println((i+1) + ANSWER_NUMBER_SPLITTER
  77. + answerList[i]);
  78. }
  79. } else {
  80. // Out error message if data in memcachedb is corrupt.
  81. System.out.println(DATA_IS_CORRUPT_MESSAGE);
  82. break;
  83. }
  84. } else {
  85. // Get true answer
  86. String trueAnswer = (String) client.get(TASK_TRUE_ANSWER
  87. + currentTaskId);
  88. if ((trueAnswer != null) && (trueAnswer.equals(msg))) {
  89. // Out congratulation message if answer is true.
  90. System.out.println(CONGRATULATION_MESSAGE);
  91. } else {
  92. // Out bad message if answer is bad.
  93. System.out.println(BAD_ANSWER);
  94. }
  95. }
  96. }
  97. // Shutdown client
  98. client.shutdown();
  99. }
  100. private static void fillMemcachedbOfTask() {
  101. // Hardcode firs task
  102. // Set task question
  103. client.set(TASK_QUESTION + 1, EXPIRED, "What is your name?");
  104. // Set task answers
  105. client.set(TASK_ANSWERS + 1, EXPIRED, "Aleksei,Petia,Katia,Sveta");
  106. // Set true task
  107. client.set(TASK_TRUE_ANSWER + 1, EXPIRED, "Aleksei");
  108. // Hardcode second task
  109. // Set task question
  110. client.set(TASK_QUESTION + 2, EXPIRED, "Do you speak english?");
  111. // Set task answers
  112. client.set(TASK_ANSWERS + 2, EXPIRED, "yes,no");
  113. // Set true task
  114. client.set(TASK_TRUE_ANSWER + 2, EXPIRED, "yes");
  115. // Hardcode task sequence
  116. client.set(TASK_SEQUENCE, EXPIRED, 2);
  117. }
  118. }
Ну вот вроде и все, ничего сложного казалось бы нет. Выше приведенный код демонстрирует основные операции для работы с memcachedb. НО! есть одно НО! это работа с memcachedb в многопоточной среде. Простейшая операция увеличения sequence для получения id новой записи, реализованная следующим образом:
  1. int nextTaskId = (Integer) client.get(TASK_SEQUENCE);
  2. nextTaskId++;
  3. client.set(TASK_SEQUENCE, EXPIRED, nextTaskId);
может привести к коллизии.
Для того чтобы таких ситуаций не возникало существют incr/decr, инкримент и дикримент соответственно. Они увеличивают/уменьшают значение ключа и возвращают результат.
Что ж я вроде сказал все что хотел сказать.
Надеюсь мой небольшой очерк вам поможет...
Всем спасибо!

Интересные ссылки по теме:
Твиттер на основе Memcachedb и PHP
memcached на пальцах

Читать далее