-неизвестно

 -Поиск по дневнику

Поиск сообщений в ATUM

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 17.02.2006
Записей:
Комментариев:
Написано: 1139




Мечты составляют половину реальности....(Жозеф ЖУБЕР) В этом мире все когда-то было мечтой...

Идея

Пятница, 14 Декабря 2012 г. 10:02 + в цитатник
Реклама авиалиний России - по всей России - с ее колоритом !

Метки:  

Корректное отображение русских шрифтов в командной строке Windows

Четверг, 13 Декабря 2012 г. 15:53 + в цитатник
Корректное отображение русских шрифтов в командной строке Windows
http://magicpast.net/windows/index.php?page=russkij-jazyk-v-cmd

Зачастую возникает надобность использовать консольные программы с консольными кодировками. Но к сожалению еще чаще случается то, что вместо русского языка отображаются квакозябры, малопохожие на русский язык.
Для того чтобы это исправить, необходимо:
в редакторе реестра (пуск - выполнить - regedit) изменить значение параметра "00000409" на "ru", по следующему адресу:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control \KeyboardLayout\DosKeybCodes

Использование putty и ssh ключей в Windows

Четверг, 13 Декабря 2012 г. 09:28 + в цитатник
http://habrahabr.ru/post/39254/

Распаковываем и запускаем ssh-keygen

Выбираем ключ ssh-rsa и длину 2048 бит. Жмем «Generate».

Ключ готов, заполняем кодовую фразу и комментарий к нему. Сохраняем приватный ключ как mykey.ppk и публичный как id_rsa.pub


2. Далее необходимо скопировать наш публичный ключ на сервер. Для этого запускаем psftp.
psftp: no hostname specified; use «open host.name» to connect
psftp> open myserver
The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
If you trust this host, enter «y» to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter «n».
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n) y
login as: root
root@myserver's password:
Remote working directory is /root
psftp>put id_rsa.pub /tmp/id_rsa.pub
local:id_rsa.pub => remote:/tmp/id_rsa.pub
psftp>


3. Ключ скопировался, теперь нужно добавить его в /root/.ssh/authorized_keys
Для этого логинимся еще раз по паролю, через putty и выполняем
ssh-keygen -i -f /tmp/id_rsa.pub >> /root/.ssh/authorized_keys

Теперь осталось добавить наш ключ в ssh-agent'a. После запуска он сидит в трее, чтобы добавить ключ кликаем правой кнопкой на «Add Key»


Вводим кодовую фразу:


Теперь логинимся в putty:
login as: root
Authenticating with public key "rsa-key-20080908" from agent


Практически все, чтобы устранить проблемы с кодировками, с кривым отображением mc в путти, исправляем локаль в настроках:

Метки:  

djvu на iPad

Среда, 12 Декабря 2012 г. 11:59 + в цитатник
Чтение djvu на iPad предварительно конвертируя djvu в PDF

Читать на iPad djvu формат можно предварительно конвертируя его в PDF. Сделать это можно с помощью двух бесплатных программ PDF Creator и WinDjView
Ищем последние версии (см. раздел Полезные ссылки) и скачиваем их, а потом устанавливаем:

Устанавливаем внимательно, так как обе программы норовят сделать вам поиск по умолчанию Яндекс и установить в систему свои панели и настройки (оно вам надо?!). Затем открываем в WinDjView наш файл djvu и нажимаем печатать. Среди принтеров выбираем PDF Creator и ждем.
За те же 5 минут мы получаем 250 страничный файл PDF, который читается многими программами (iBooks, PDF Reader, Comrade и др.)

Метки:  

java random

Среда, 12 Декабря 2012 г. 11:50 + в цитатник

int randomNumber = Math.abs( random.nextInt() % UPPER_LIMIT );

Метки:  

Рабочие примеры реализации алгоритмов - AES, DES, RSA : Bouncy Castle (cryptography)

Среда, 12 Декабря 2012 г. 11:31 + в цитатник
Bouncy Castle (cryptography)

import java.io.*;
import java.math.*;
import java.security.*;
import org.bouncycastle.crypto.*;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.crypto.engines.*;
import org.bouncycastle.crypto.encodings.*;
import org.bouncycastle.crypto.generators.*;
import org.bouncycastle.crypto.modes.*;
import org.bouncycastle.crypto.paddings.*;
import org.bouncycastle.crypto.digests.*;
import org.bouncycastle.crypto.signers.*;
public class CryptoEngine {
 private byte [] AESkey;
 private byte [] AESinitV;
 private byte [] salt;
 private RSAKeyParameters RSAprivKey;
 private RSAKeyParameters RSApubKey;
 public CryptoEngine () {
  try {
   Class c = this.getClass();
   InputStream is;
   is = c.getResourceAsStream("/keys/AESkey.dat");
   AESkey = readFromStream(is);
   is.close();
   is = c.getResourceAsStream("/keys/AESinitV.dat");
   AESinitV = readFromStream(is);
   is.close();
   SecureRandom sr = new SecureRandom();
   salt = new byte [16];
   sr.nextBytes(salt);
   is = c.getResourceAsStream("/keys/RSAmod.dat");
   BigInteger RSAmod = new BigInteger(readFromStream(is));
   is.close();
   is = c.getResourceAsStream("/keys/RSAprivExp.dat");
   BigInteger RSAprivExp = new BigInteger(readFromStream(is));
   is.close();
   is = c.getResourceAsStream("/keys/RSApubExp.dat");
   BigInteger RSApubExp = new BigInteger(readFromStream(is));
   is.close();
   is = c.getResourceAsStream("/keys/RSAdp.dat");
   BigInteger RSAdp = new BigInteger(readFromStream(is));
   is.close();
   is = c.getResourceAsStream("/keys/RSAdq.dat");
   BigInteger RSAdq = new BigInteger(readFromStream(is));
   is.close();
   is = c.getResourceAsStream("/keys/RSAp.dat");
   BigInteger RSAp = new BigInteger(readFromStream(is));
   is.close();
   is = c.getResourceAsStream("/keys/RSAq.dat");
   BigInteger RSAq = new BigInteger(readFromStream(is));
   is.close();
   is = c.getResourceAsStream("/keys/RSAqInv.dat");
   BigInteger RSAqInv = new BigInteger(readFromStream(is));
   is.close();
   RSAprivKey = new RSAPrivateCrtKeyParameters(RSAmod, RSApubExp,
            RSAprivExp, RSAp, RSAq, RSAdp, RSAdq, RSAqInv);
   RSApubKey = new RSAKeyParameters(false, RSAmod, RSApubExp);
  } catch (Exception e) {
   e.printStackTrace();
  }
  return;
 }
 public void generateAESKey () throws Exception {
  SecureRandom sr = new SecureRandom();
  AESkey = new byte [16];
  sr.nextBytes(AESkey);
  AESinitV = new byte [16];
  sr.nextBytes(AESinitV);
 }
 public void generateRSAKeyPair () throws Exception {
  SecureRandom sr = new SecureRandom();
  BigInteger pubExp = new BigInteger("10001", 16);
  RSAKeyGenerationParameters RSAKeyGenPara =
     new RSAKeyGenerationParameters(pubExp, sr, 1024, 80);
  RSAKeyPairGenerator RSAKeyPairGen = new RSAKeyPairGenerator();
  RSAKeyPairGen.init(RSAKeyGenPara);
  AsymmetricCipherKeyPair keyPair = RSAKeyPairGen.generateKeyPair();
  RSAprivKey = (RSAPrivateCrtKeyParameters) keyPair.getPrivate();
  RSApubKey = (RSAKeyParameters) keyPair.getPublic();
 }
 public byte [] AESLiteEncrypt (byte [] toEncrypt) throws Exception {
  BufferedBlockCipher cipher =
       new PaddedBufferedBlockCipher(
        new CBCBlockCipher(new AESLightEngine()));
  // If initV is not given, the program will assume all zeros
  ParametersWithIV piv = new ParametersWithIV (
           (new KeyParameter(AESkey)), AESinitV);
  cipher.init(true, piv);
  byte[] result = new byte[cipher.getOutputSize(toEncrypt.length)];
  int len = cipher.processBytes(toEncrypt, 0, toEncrypt.length, result, 0);
  try {
   cipher.doFinal(result, len);
  } catch (CryptoException ce) {
   result = (new String("Cipher error")).getBytes();
   ce.printStackTrace();
  }
  return result;
 }
 public byte [] AESLiteDecrypt (byte [] toDecrypt) throws Exception {
  BufferedBlockCipher cipher =
       new PaddedBufferedBlockCipher(
        new CBCBlockCipher(new AESLightEngine()));
  ParametersWithIV piv = new ParametersWithIV (
           (new KeyParameter(AESkey)), AESinitV);
  cipher.init(false, piv);
  byte[] result = new byte[cipher.getOutputSize(toDecrypt.length)];
  int len = cipher.processBytes(toDecrypt, 0, toDecrypt.length, result, 0);
  try {
   cipher.doFinal(result, len);
  } catch (CryptoException ce) {
   result = (new String("Cipher error")).getBytes();
   ce.printStackTrace();
  }
  return result;
 }
 public byte [] AESFastEncrypt (byte [] toEncrypt) throws Exception {
  BufferedBlockCipher cipher =
       new PaddedBufferedBlockCipher(
        new CBCBlockCipher(new AESFastEngine()));
  // If initV is not given, the program will assume all zeros
  ParametersWithIV piv = new ParametersWithIV (
           (new KeyParameter(AESkey)), AESinitV);
  cipher.init(true, piv);
  byte[] result = new byte[cipher.getOutputSize(toEncrypt.length)];
  int len = cipher.processBytes(toEncrypt, 0, toEncrypt.length, result, 0);
  try {
   cipher.doFinal(result, len);
  } catch (CryptoException ce) {
   result = (new String("Cipher error")).getBytes();
   ce.printStackTrace();
  }
  return result;
 }
 public byte [] AESFastDecrypt (byte [] toDecrypt) throws Exception {
  BufferedBlockCipher cipher =
       new PaddedBufferedBlockCipher(
        new CBCBlockCipher(new AESFastEngine()));
  ParametersWithIV piv = new ParametersWithIV (
           (new KeyParameter(AESkey)), AESinitV);
  cipher.init(false, piv);
  byte[] result = new byte[cipher.getOutputSize(toDecrypt.length)];
  int len = cipher.processBytes(toDecrypt, 0, toDecrypt.length, result, 0);
  try {
   cipher.doFinal(result, len);
  } catch (CryptoException ce) {
   result = (new String("Cipher error")).getBytes();
   ce.printStackTrace();
  }
  return result;
 }
 // Get use password to generate symmetric key with (or without IV)
 // To be used in an AES underlying cipher
 private CipherParameters getAESPasswdKey (char [] passwd) throws Exception {
  PBEParametersGenerator generator =
    new PKCS12ParametersGenerator(new SHA1Digest());
  generator.init(
    PBEParametersGenerator.PKCS12PasswordToBytes(passwd),
    salt, 1024);
  // Generate a 128 bit key w/ 128 bit IV
  ParametersWithIV key =
   (ParametersWithIV)generator.generateDerivedParameters(128, 128);
  // Generate a 128 kit key
  // CipherParameters key = generator.generateDerivedParameters(128);
  return key;
 }
 // Password based encryption using AES
 public byte [] AESPasswdEncrypt (byte [] toEncrypt, char [] passwd)
                    throws Exception {
  ParametersWithIV key = (ParametersWithIV) getAESPasswdKey(passwd);
  // The following code uses an AES cipher to
  // encrypt the message
  BufferedBlockCipher cipher =
       new PaddedBufferedBlockCipher(
        new CBCBlockCipher(new AESFastEngine()));
  cipher.init(true, key);
  byte[] result = new byte[cipher.getOutputSize(toEncrypt.length)];
  int len = cipher.processBytes(toEncrypt, 0, toEncrypt.length, result, 0);
  try {
   cipher.doFinal(result, len);
  } catch (CryptoException ce) {
   result = (new String("Cipher error")).getBytes();
   ce.printStackTrace();
  }
  return result;
 }
 // Password based decryption using AES
 public byte [] AESPasswdDecrypt (byte [] toDecrypt, char [] passwd)
                    throws Exception {
  ParametersWithIV key = (ParametersWithIV) getAESPasswdKey(passwd);
  // The following code uses an AES cipher to
  // decrypt the message
  BufferedBlockCipher cipher =
       new PaddedBufferedBlockCipher(
        new CBCBlockCipher(new AESFastEngine()));
  cipher.init(false, key);
  byte[] result = new byte[cipher.getOutputSize(toDecrypt.length)];
  int len = cipher.processBytes(toDecrypt, 0, toDecrypt.length, result, 0);
  try {
   cipher.doFinal(result, len);
  } catch (CryptoException ce) {
   result = (new String("Cipher error")).getBytes();
   ce.printStackTrace();
  }
  return result;
 }
 // Get use password to generate a triple DES symmetric key
 private DESedeParameters getDESedePasswdKey (char [] passwd)
                       throws Exception {
  PBEParametersGenerator generator =
    new PKCS12ParametersGenerator(new SHA1Digest());
  generator.init(
    PBEParametersGenerator.PKCS12PasswordToBytes(passwd),
    salt, 1);
  KeyParameter rawKey =
   (KeyParameter) generator.generateDerivedParameters(128);
  byte [] keyBytes = rawKey.getKey();
  DESedeParameters.setOddParity(keyBytes);
  DESedeParameters key = new DESedeParameters(keyBytes);
  return key;
 }
 // Password based encryption using DESede
 public byte [] DESedePasswdEncrypt (byte [] toEncrypt, char [] passwd)
                    throws Exception {
  DESedeParameters key = (DESedeParameters) getDESedePasswdKey(passwd);
  BufferedBlockCipher cipher =
       new PaddedBufferedBlockCipher(
        new CBCBlockCipher(new DESedeEngine()));
  cipher.init(true, key);
  byte[] result = new byte[cipher.getOutputSize(toEncrypt.length)];
  int len = cipher.processBytes(toEncrypt, 0, toEncrypt.length, result, 0);
  try {
   cipher.doFinal(result, len);
  } catch (CryptoException ce) {
   result = (new String("Cipher error")).getBytes();
   ce.printStackTrace();
  }
  return result;
 }
 // Password based decryption using DESede
 public byte [] DESedePasswdDecrypt (byte [] toDecrypt, char [] passwd)
                    throws Exception {
  DESedeParameters key = (DESedeParameters) getDESedePasswdKey(passwd);
  BufferedBlockCipher cipher =
       new PaddedBufferedBlockCipher(
        new CBCBlockCipher(new DESedeEngine()));
  cipher.init(false, key);
  byte[] result = new byte[cipher.getOutputSize(toDecrypt.length)];
  int len = cipher.processBytes(toDecrypt, 0, toDecrypt.length, result, 0);
  try {
   cipher.doFinal(result, len);
  } catch (CryptoException ce) {
   result = (new String("Cipher error")).getBytes();
   ce.printStackTrace();
  }
  return result;
 }
 // Public key encrypt using RSA
 public byte [] RSAEncrypt (byte [] toEncrypt) throws Exception {
  if (RSApubKey == null)
   throw new Exception("Generate RSA keys first!");
  AsymmetricBlockCipher eng = new RSAEngine();
  eng = new PKCS1Encoding(eng);
  eng.init(true, RSApubKey);
  return eng.processBlock(toEncrypt, 0, toEncrypt.length);
 }
 // private key decrypt
 public byte [] RSADecrypt (byte [] toDecrypt) throws Exception {
  if (RSAprivKey == null)
   throw new Exception("Generate RSA keys first!");
  AsymmetricBlockCipher eng = new RSAEngine();
  eng = new PKCS1Encoding(eng);
  eng.init(false, RSAprivKey);
  return eng.processBlock(toDecrypt, 0, toDecrypt.length);
 }
 // RSA signature
 public byte [] RSASign (byte [] toSign) throws Exception {
  if (RSAprivKey == null)
   throw new Exception("Generate RSA keys first!");
  SHA1Digest dig = new SHA1Digest();
  RSAEngine eng = new RSAEngine();
  PSSSigner signer = new PSSSigner(eng, dig, 64);
  signer.init(true, RSAprivKey);
  signer.update(toSign, 0, toSign.length);
  return signer.generateSignature();
 }
 // RSA signature verification
 public boolean RSAVerify (byte [] mesg, byte [] sig) throws Exception {
  if (RSApubKey == null)
   throw new Exception("Generate RSA keys first!");
  SHA1Digest dig = new SHA1Digest();
  RSAEngine eng = new RSAEngine();
  PSSSigner signer = new PSSSigner(eng, dig, 64);
  signer.init(false, RSApubKey);
  signer.update(mesg, 0, mesg.length);
  return signer.verifySignature(sig);
 }
 private byte [] readFromStream (InputStream is) throws Exception {
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  byte [] b = new byte[1];
  while ( is.read(b) != -1 ) {
    baos.write(b);
  }
  byte[] result = baos.toByteArray();
  baos.close();
  return result;
 }
}


* This source code was highlighted with Source Code Highlighter.

Метки:  

Ehcache в качестве RESTful сервера кеширования и PHP

Вторник, 11 Декабря 2012 г. 10:16 + в цитатник
Ehcache в качестве RESTful сервера кеширования и PHP
http://abrdev.com/?p=996

Что означают эти опции:

name - имя кеша, которое будет использоваться для доступа (будет в URL, поэтому на содержание накладываются те же ограничения, лучше всего - краткое и четко обозначающее тип хранимых данных). В рамках одного сервера может быть множество кешей с разными именами.
maxElementsInMemory - максимальное количество элементов, которые размещаются в памяти
maxElementsOnDisk - максимальное количество элементов на диске (0 - без ограничений)
eternal - указывает, что можно игнорировать установки жизни кеша, тогда элементы будут всегда в кеше, пока вы их не удалите вручную
overflowToDisk - указывает, могут ли элементы быть вытеснены на диск, если достигнуто максимальное количество объектов в памяти
timeToIdleSeconds - время от последнего доступа к объекту до момента признания его невалидным.(если он не помечен как eternal). Опциональный параметр
timeToLiveSeconds - время жизни элемента (с версии 1.6, если не ошибаюсь, эта опция может быть задана для каждого отдельного объекта кеша
diskPersistent - указывает на сохранение состояния кеша на диске между рестартами
diskExpiryThreadIntervalSeconds - периодичность запуска процесса проверок объектов на диске на истечение TTL (времени жизни).
diskSpoolBufferSizeMB - объем пула, который выделен кешу для буферизации записи на диск. Когда пул заполнен, асинхронно вызывается команда записи на диск состояния кеша
memoryStoreEvictionPolicy - обозначает стратегию определения, какие объекты кеша должны быть вытеснены на диск. Может быть LRU (Least Recently Used), по дате последнего использования, FIFO (First In First Out, первый добавлен, первый вытеснен) и LFU (Less Frequently Used, по частоте использования)
Мы пока не обсуждаем варианты репликации - это уже углубленная специфика, о которой пусть лучше расскажут более компетентные специалисты.


cache name="testRestCache"
maxElementsInMemory="10000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="true"
diskSpoolBufferSizeMB="4"
maxElementsOnDisk="1000000000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="3600"
memoryStoreEvictionPolicy="LFU"

И так, наш кеш сконфигурирован так, чтобы держать в памяти 10 тыс. элементов, на диске 1 млрд, не использовать настройки времени жизни, обеспечить постоянство данных между перезагрузками. Объем пула для дисковой записи я выбрал достаточно небольшим, а время проверок на срок жизни дисковых элементов - очень большим (но думаю надо больше, в идеале - посмотрим, можно ли отключить вообще). Для чего именно такая конфигурация? Мне интересно попробовать на базе этого кеша сделать простую key-value базу данных (сегодня это очень популярная тема), при этом обеспечив себе возможность как прямого обращения к кешу из внешних сервисов, так и изнутри РНР веб-приложения. Один нюанс - даже если вам не нужна проверка на время жизни и необходим постоянный кеш, не устанавливайте параметры timeToIdle/timeToLive в 0, иначе сервер может не запускаться (вернее - сервис кеша, сам сервер стартует по выдает исправно 404 ошибку).

Для проверки сохраните отредактированный файл ehcache.xml и перезапустите сервер. Теперь откроем в браузере URL: http://localhost:8080/ehcache/rest/testRestCache - вы должны получить XML-документ со всеми настройками кеша, а также текущую статистику использования кеша (объем, количество данных, процент попадания и промахов) - в дальнейшем это можно разбирать программно, чтобы выводить в нужном виде (например, в админке).

В дальнейшем я буду рассматривать только REST-часть, для работы через SOAP вам надо поменять в URL rest на soap, получить описание сервисов в WSDL-формате и т.п. Для производительности я у себя просто отключил все неиспользуемое, в том числе ненужные мне кеши и доступ по SOAP-протоколу. Настройки сервлетов доступны в файле web.xml в директории /war/WEB-INF.

Работа с кешем заключается в отправке запросов по HTTP-протоколу и разбору ответа. В случае ошибки, ответ будет в формате text/plain, а в теле запроса будет текст ошибки, HTTP-код будет 404 - например, вы обратились к несуществующему кешу или элементу, тогда ответом будет строка "Element not found: 333" (если вы запросили элемент с ключем 333). Но это справедливо для тех URL, которые обслуживаются сервлетом EHcache, если же ошибка будет в другой части, вы получите стандартную 404 страницу ошибки от GlassFish, которая менее приспособлена к автоматическому разбору.

Работать можно как с сервером вообще (с менеджером кешей), так и индивидуально с каждым кешем и элементом, для этого просто дополните строку URL и используйте нужный метод с параметрами.

Для всего кеш (CacheManager-а):

Integrating Java with C++

Вторник, 11 Декабря 2012 г. 10:05 + в цитатник
Integrating Java with C++

http://www.javaworld.com/javatips/jw-javatip17.html


Getting the source code
If you'd like the complete source code for the program developed in this article (complete with Solaris Makefile), click for javaAndC++.tar.gz, or for javacpp.zip. If you'd just like to browse, here are the source files:

Java source files:

JavaObjectHolder.java
NumberListObserver.java
NumberListProxy.java
TestNumberList.java
C++ source file:
JavaObservableProxy.h
JavaObservableProxy.cc
NumberList.h
NumberList.cc
NumberListProxyImpl.cc
Observable.h
Observable.cc
Observer.h
Other
Makefile (for Solaris-based systems)

Метки:  

PostgreSQL оптимизация

Понедельник, 10 Декабря 2012 г. 11:32 + в цитатник

Метки:  

PostgreSQL в веб-приложениях

Понедельник, 10 Декабря 2012 г. 10:56 + в цитатник
PostgreSQL в веб-приложениях
Сегодня хотел бы рассказать вам об использовании Postgres’а в веб-приложениях, а именно, о кластерных решениях и понятиях отказоустойчивости, балансировки, репликации и масштабирования, о решениях, которые существуют в Postgres’е для устранения данных проблем. Я открываю череду докладов на РИТ’е, посвящённых Postgres’у. Начну с небольшого вступления. Что такое Postgres, возможно, знают не все. Далее будет некоторый бриф, посвященный этому понятию. Потом расскажу, что собой представляет всё это.

Затем перейдём к самой интересной части: непосредственно к разговору о решениях по отказоустойчивости, балансировке, репликации и масштабированию. Будет интересно: новые решения, о которых мало кто знает.

Postgres — это самая продвинутая из открытых СУБД в мире. Есть слоган, и, в принципе, с ним мало кто спорит.

Немного расскажу об основных понятиях. Postgres — это надёжность и устойчивость на любых нагрузках в силу своей архитектуры. Прежде всего, это превосходная поддержка от community. Живой пример: буквально позавчера у человека, мигрировавшего с MySQL, возникла какая то проблема, он написал в рассылку и по привычке, думает долго будет, пошёл пить кофе, а по возвращении обнаруживает 15 сообщений, как решать его проблему. То есть community работает. Postgres — это кроссплатформенность, никаких проблем с операционной системой нет, можете использовать, что угодно.

Postgres — это высокий уровень соответствия стандартам SQL 92, 99 и 2003 гг., один из самых высоких среди СУБД. Есть интерфейсы для любых языков: даже нет смысла все перечислять. Для людей, которым не нравится работать в консоли и с текстом, существуют административные утилиты. Можно кликать мышкой и настраивать сервер, как угодно.

Я сделал кучу малу из базвордов. Просто зачитаю. Здесь, наверное, только 10% функциональности. В Postgres есть представления, sequences, наследование, joins, subselects, ссылочная целостность, rules triggers, пользовательские функции, хранимые процедуры.
Есть огромное количество языков: PL/SQL, PgSQL, Perl, PHP, Tcl, Shell, Ruby, Python, расширяемые типы данных (можете свои придумывать), горячий backup. Postgres — это ACID совместимая база, то есть настоящая база данных. Postgres поддерживает функциональные и частичные индексы, интернационализацию, Unicode. Есть отличный полнотекстовый поиск, очень быстрый и гибкий в конфигурации. Есть поддержка XML, есть SSL. Есть всё, что угодно.

Это база для «серьёзных ребят»: её используют Яндекс (с недавнего времени), Рамблер, РБК в некоторых проектах, Работа.ру, Вебальта и, например, компания Skype, которую Илья Сегалович вчера в приветственном слове так хорошо охарактеризовал. Плюс очень много других анонимных проектов. Потом в кулуарах расскажу, если кому интересно.

Теперь собственно о четырёх понятиях. Отказоустойчивость включает в себя понятие failover. У нас есть некоторый сервер, который общается с приложением, и есть второй сервер, который с ним синхронизуется. Вдруг случается неприятность: в него попадает молния. Что-то должно взять и переключить нагрузку на резервный сервер, эта услуга и называется failover.

Балансировка нагрузки. Есть некоторый сервер Load Balancer, непосредственно с которым общается приложение. Что стоит за ним, приложению не важно. А Load Balancer берёт и распределяет нагрузку на несколько других серверов.

Масштабирование. Есть набор серверов. Приложению не важно, как они устроены, главное, что их много. И подчеркиваю, пишите крупные приложения с расчётом на scale-out, то есть на горизонтальное масштабирование, когда вы покупаете много одинаковых горизонтальных ящиков. В противоположность scale-up, когда вы покупаете один большой ящик и растите его, растите и растите. Инвесторы любят scale-out. Если есть в проекте n пользователей сервиса на одном сервере, который стоит m денег, инвестору понятно, что если он хочет в k раз увеличить кол-во пользователей, то ему нужно затратить k*m денег, а не больше. Это называется scale-out.

Теперь репликация. Вкратце расскажу о том, какие виды репликации бывают, чтобы все себе это хорошо представляли. Простейший вид репликации это Master/Slave. Master — это сервер, на который идут модифицирующие запросы. Slave — сервер, который дублирует его. Я не сказал про асинхронность: если падает сетевое соединение между серверами, то, когда оно восстанавливается, ваш Slave (сервер, который справа) берёт и спокойно догоняет Master.

Master/Slave, синхронная репликация, означает, что модификации Master’а синхронно дублируются на Slave. Чуть позже объясню, что это.

Multi-Master репликация подразумевает наличие нескольких серверов, которые одновременно принимают на себя модифицирующие запросы, insert, delete, update. Синхронная в данном случае означает, что до того момента, пока все сервера не подтвердили получение изменений, то есть не сказали accept модифицирующим изменениям, изменения не комитятся: все сервера ждут. Собственно, в этом и заключается понятие синхронности. Этим же вызван некоторый bottleneck, то есть узкое место. Это связано с тем, что все сервера ждут, пока последний из них не скажет accept, потом только наступает commit.

И последний тип репликации — это асинхронный Multi-Master. Надо сказать, что это мечта человечества. Она не реализуется в общем виде, она антипаттерн. Если у вас приложение или бизнес требуют асинхронного Multi-Master’а, вам нужно что-то делать либо с приложением, либо с бизнесом. В общем виде проблему не решить по причине конфликтов. Вы можете научить базу данных разрешать какие-то конкретные конфликты. Например, на одном Master’е пользователь обновил запись о своём адресе, а на другом запись о своём телефоне — вот такой конфликт базу данных можно научить разрешать. Но если возникает что-то сложное, то, понятно, что без ручного вмешательства проблему решить невозможно, поэтому асинхронный Multi-Master это зло.

Теперь перейдём к более интересной части, конкретно к решениям. Первое из того, что стоит упомянуть это Pgpool-II. Прошу отметить, что это совершенно новое решение. Это не Pgpool-I. Это Pgpool, написанный заново авторами первой версии. Он решил все проблемы, которые были ранее, то бишь, сняты все ограничения на работу с серверами, с количеством серверов. Из картинки должно быть понятно, что простейшее применение, это балансировка нагрузки, когда на все сервера распространяются модифицирующие изменения: insert, update, delete, а на какой-то конкретный, в рамках балансировки, уходят select’ы.

Список фич Pgpool’а короткий. Во-первых, основное его значение это менеджер соединений, connection pooling с кэшем, то есть можно кэшировать соединение. Во-вторых, очень полезная вещь Failover, я уже говорил о ней. Это обнаружение отказа и переключение нагрузки на резервный сервер: ему не страшно, если падает машина. Репликация. Из предыдущего снимка вы должны были понять, что Pgpool является синхронной мульти-мастер системой. Он ждёт, пока все сервера скажут accept, и после этого коммитится, таким образом, удостоверяясь, что изменения попали на все Master. Его можно тюнить. Bottleneck, о котором я говорил раньше, можно немножко улучшать, но при этом мы теряем надёжность.
Вопрос: Блокирует вот эта синхронная мульти-мастер запись?
Иван: Как транзакция блокирует на raw-level lock. Таблицы сами не блокируются. Об этом я расскажу позже.

Pgpool-II занимается балансировкой нагрузки: можно назначать веса серверам. В Pgpool-II есть очень полезная вещь, Master/Slave режим: когда вам не нравится репликация на Pgpool’е, вы можете поставить другой движок и сказать Pgpool’у, что есть другой движок репликации (Slony или WAL, всё, что угодно). Совсем недавно появилась возможность параллельного выполнения запросов. Что это такое? На Pgpool приходит запрос, например, по поиску. Сервер Pgpool переписывает его таким образом, чтобы на отдельные ноды, на отдельные узлы кластера ушли более мелкие подзапросы в соответствии с каким-то правилом. То есть можно в n раз, где n — число серверов, ускорять ваши поиски и любые select операции. У Pgpool-II, как я говорил, нет ограничений на число узлов кластера, как это было в первом Pgpool’е.

Простейшая схема от авторов. Запрос, попадая в Pgpool, проверяется сначала на кэш, затем парсится, если нужно, переписывается. Пользователь сам задаёт правило, какие запросы переписывать и как нужно это делать. Дальше попадает в движок параллельного выполнения запросов. Переписанные запросы отправляются на отдельные узлы кластера. Дальше мёржится, сортируется, производятся все необходимые действия.

Есть замечательный интерфейс управления, но всё это нужно писать руками.

Здесь главный график: по y — транзакции в секунду, по x — количество одновременных соединений. Зелёная линия — это один Postgres сервер, красная — это Pgpool, по-моему, с девятью серверами. Количество транзакций в секунду: чем больше, тем лучше. Соответственно с 15-20 соединений происходит линейный рост. То есть вы кинули деньги на девять серверов, вы получили в девять раз лучше перфоменс.

С Pgpool’ом закончили. Slony-1. Самая известная репликация для Postgres. Все пользователи Postgres, так или иначе, слышали о ней. Она представляет собой мастер на любое количество Slave’ов репликации. Это асинхронная система: в плане распространения транзакций нет penalty на ожидание accept’ов всех серверов. Настраивается просто. Поддерживает десятки Slave’ов, и , в принципе, нет ограничений. Поддерживает каскады реплицируемых серверов. Если у вас сложная топология Postgres кластера, то сервера на разных континентах, линки падают, происходит всё, что угодно.

Вы можете организовать любое подобие, вот такой системы. Главное, что всё асинхронно. Сеть упала — на Master’е изменения, сеть поднялась — Slave аккуратно всё догнал. Система надёжная и проверенная временем, активно развивается, так что проблем с ней никаких быть не должно. Самая известная репликация.

PgCluster. Буду говорить в порядке перечисления, чтобы было понятно. Синхронный мультимастер. Он занимается балансировкой нагрузки. В нём есть Failover-система. Кластер состоит из трёх типов серверов: это ноды кластера, балансировщик нагрузки и репликатор. Всё настраивается довольно сложно, но для ленивых есть готовое решение из коробки от наших партнёров Cybertec. Просто ставите, и у вас запускается сервер: всё настроено, всё работает.

Не мог не сказать о WAL shipping. Хотя это и не совсем репликация, это трансфер логов, о нём должны знать все пользователи Postgres’а. Postgres (база данных, совместимая с принципами ACID) ведёт лог транзакций, которые не рекомендуется отключать. Этот лог транзакций можно переносить и проигрывать на Slave сервере. Таким образом, получается асинхронная система. Она встроена в Postgres, не нужно ничего доставлять для этого. Это не репликация. Это hot backup, то есть у вас будет небольшой лаг, десятки секунд, например, Master’ом и Slave’ом. В настоящий момент нельзя читать со Slave’а, но я расскажу об этом позже.

Наконец, самое интересное. Свежие проекты компании Skype. Как я уже говорил, Skype работает на Postgres’е. Инвестором при последней покупке была поставлена задача — выдерживать нагрузку в миллиард пользователей. Узкое место — база данных. Ребята решили проблему, причём о путях стало известно год назад, и буквально в марте выложили свои наработки в Open Source под BSD лицензией. Сейчас расскажу, что это такое. Во-первых, PL/Proxy — это язык, который занимается проксированием запросов. Это язык, в котором на прокси-сервере создается хранимая процедура с той же сигнатурой, что и на узлах кластера. В теле функции просто указывается путь до нужной ноды или говорится, что нужно дёрнуть функцию либо со всех нод одновременно, либо с какой-то конкретной, либо со случайной. Таким образом, можно устраивать линейное, горизонтальное, то самое, Scale Out масштабирование системы, построенной на хранимых процедурах. Во-вторых, существует PgBouncer. Это очень лёгкий менеджер соединений, 2 килобайта на соединение. На простых машинах можно кэшировать огромное количество соединений, к backend’ам Postgres’а. Также очень важный проект Sky Tools. Это набор утилит управления кластером.

Что такое Sky Tools? Во-первых, это PgQ, обобщённая очередь. Вы имеете SQL интерфейс, имеете доступ к модифицирующим событиям, которые происходят в базе. Вы можете подписывать на очередь одного или n, где n-любое количество, подписчиков и как-то обрабатывать события. Это немного низкий уровень, но, в принципе, для администраторов баз данных подойдёт. Существует возможность очень легко организовывать свои custom’овые репликации. Далее стоит упомянуть WAL Manager, тот самый трансфер логов. Skype выпустило решение, которое позволяет администратору очень легко производить setup WAL’а и организовывать hot failover. Появилась возможность быстро поднимать WAL Slave, на котором в данное время не разрешены read запросы, чтение пока не поддерживается. Так или иначе, вы можете решить эту проблему очень быстро. Еще одна полезная вещь это Londiste, собственно средство репликации. В основе Londiste лежит PgQ. По сути дела это некоторое подобие Slony, но упрощённое, поддерживающее репликацию на уровне таблиц. Нет необходимости реплицировать всю базу, вы можете реплицировать только таблицы. Это очень важно, например, для связи OLTP баз данных, баз данных под Web приложением, для связи её с OLAP базами данных, когда нужны аналитические запросы. Запомните эти слова. Это очень перспективные наработки. Они сейчас в числе самых активно развиваемых проектов под SQL.

Пара картинок от Хану Кроссинга, архитектора баз данных в Skype’е. В качестве примера, как росла система. Сначала был один сервер, потом их стало три, потом второй зареплицировали Слонами, а третий зариплицировали Питром.

Картинка о PL/Proxy. Как я говорил, на прокси-сервере база данных, в которой установлен PL/Proxy язык. Создаются функции с такой же сигнатурой, которые дёргают по заранее указанному правилу одну или другую ноду, в данном случае их две. И Skype. Из каждой ноды кластера, которых может быть очень много, сотни у Skype, организован WAL backup, то есть host and buy бесплатная репликация, о которой я говорил и ещё скажу несколько слов позже.

Таким образом, можно легко внести в систему резервирование по прокси-серверам, чтобы прокси-сервер не был единственной точкой отказа. В квадратиках PL/Proxy сервера, каждый из них общается со всеми нодами кластера. Кружком обозначен PgBouncer, тот самый лёгкий и быстрый менеджер соединения. PL/Proxy, на самом деле, дёргает PgBouncer, а не непосредственно Postgres сервера на нодах. Решены две вечные проблемы базы данных: горизонтальное масштабирование OLTP-системы и трансфер нужных кусков в OLAP базы с помощью Londiste, о чём я уже говорил.

Да, счастье есть. В CVS этим летом будет закомичена фича, позволяющая в WAL Slave’ах использовать их в read-only запросах. Что мы будем иметь? Мы будем иметь абсолютно бесплатную для мастера (на мастер не будет создаваться никакой дополнительной нагрузки, то есть 0%, вы не платите за это денег) возможность реплицировать его на любое количество Slave’ов, просто перенося лог транзакции. Это будет встроено в Postgres. Я надеюсь, что эта возможность появится в версии 8.4, выход которой ожидается этим летом. Всем нужно будет использовать, потому что это бесплатно в плане penalty на производительность мастера.

Вопрос: А куда вы выложите статью?

Я думаю, что на brief, на opennet, на Linux.org, на postgresmen.

Вопрос: Как оказалось, любая нода это слабое место кластера, от неё ожидается accept. Если она медленная, это означает, что весь кластер в результате медленный. В горизонтальном масштабировании ситуация такая же?

Хороший вопрос. Дело в том, что для горизонтального масштабирования лучше не использовать Multi-Master. Лучше строить приложения, партицируя свои данные, то есть, разбивая таблицу пользователей на 26 узлов по первой букве. Multi-Master синхронный, асинхронного нет, ни одного решения, ни в одной базе. Если говорят, что он есть, шарлатаны, не слушайте их. Соответственно не используйте синхронный Multi-Master, потому что нужно ждать самую медленную ноду. Это верно. Skype не о том. Это о партицировании данных и о том, как организовать удобный доступ к партицированным данным. Еще одно достоинство заключается в том, что разработчики приложения (у них доступ организован через функции) даже не знают, сколько там серверов. То есть администратор баз данных может как угодно масштабировать.

Если мы партицируем данные, или у нас должно быть где-то одно звено слабое, которое будет знать, где данные. Какие проблемы могут возникнуть в том случае, когда мы добавляем новый сервер, новую ноду, чтобы данные как-то рассосались? Не возникает ли там каких-то задержек в случае добавления новых серверов? Нет ли какого-то звена, которое будет управлять сегментированием данных по нодам?

Сегментированием управляете вы, потому что в теле PL/Proxy функции вы задаёте путь до ноды, которую можно дёрнуть. Например, нужно дёрнуть ноду номер 1, если запрос идёт к пользователю с логином, начинающимся на букву А. Другое дело, что в текущей комплектации PL/Proxy требуется рестарт прокси-сервера после добавления ноды. Это не очень хорошо, но у Skype’а есть идеи, как бороться с этой проблемой. Возможно, это будет сделано. Простейший вариант: можно сделать один резервированный сервер с backup’ом, который хранит в себе хеш-функции для определения, какую ноду нужно дёрнуть при данном запросе. Это решаемо.

Какие требования по железу, по производительности для репликатора?

Это хороший вопрос. На него можно долго отвечать. Суть заключается в том, что репликатор это CPU-Limited система. В нем нет нагрузки на подсистему ввода-вывода, потому что он, по сути, координирует только работу в нод кластерах, просто отслеживает, как правильно отправлять. Например, если одновременно пришли два update’а, как выполнить их на нодах кластера, чтобы не возникло deadlock’ов. При неграмотном построении приложений можно получать deadlock’и, тогда у вас одна из транзакций будет отказываться. По сути дела репликатор занимается координацией. Покупайте большой CPU.

Язык Proxy позволяет обращаться к внешним файлам, внешним данным, или, может быть, сам прокси-сервер создаёт себе какую-то внутреннюю базу?

Прокси-сервер представляет собой SQL базу данных с языком, установленным внутри. Вы можете в теле функции выполнять любые запросы. Вы можете коннектиться к другим базам данных. Никакого ограничения нет. Но основная направленность, основная цель — создать функцию с такой же сигнатурой, в которой указывается путь до ноды, которую необходимо дёрнуть в данном запросе. Если вам нужен какой-то сложный SQL, именно на прокси-сервере, тогда потребуется, скорее всего, написать отдельную функцию в этой базе. Но это можно, да.

Метки:  

Tomcat clustering

Воскресенье, 09 Декабря 2012 г. 22:40 + в цитатник
http://voituk.kiev.ua/2007/06/25/tomcat-cluster/

Эта заметка посвящена тому, как развернуть кластер из Tomcat серверов и настроить простую балансировку нагрузки для кластера.

Начнем сначала. Зачем нужен кластер? Обычным приложениям, которые обслуживают относительно небольшой поток пользователей и к которым не предъявляются серьезные требования со стороны бизнеса, кластер, возможно и не пригодится.

Совсем по-другому обстоят дела с теми приложениями, которые являются ключевыми для функционирования бизнеса, к примеру, приложения которые обрабатывают биллинговые операции. Если “ляжет” сервис такого рода, то некоторый бизнес-процесс, тоже перестанет функционировать.


Назначение кластера: повысить общую устойчивость и масштабируемость системы. Устойчивость системы повышается за счет того, что запросы пользователей обрабатываются не одним сервером, а сразу несколькими. Поэтому в случае сбоя одного из серверов, или при необходимости перезагрузки, сервис будет продолжать нормально функционировать.

Что касается масштабируемости: увеличить производительность системы можно за счет расширения кластера. То есть, если два сервера не справляются с задачей, то довольно просто поставить третий, подключить его к кластеру и увеличить производительность системы на 50%. Надо заметить, что расширять кластер таким образом бесконечно нельзя, есть некоторые сдерживающие факторы: к примеру, объем трафика, который необходим для передачи данных сессий между нодами кластера. Об этом чуть позже.

В этой заметке приведен рецепт развертывания кластера из нескольких Tomcat серверов на одной рабочей станции. Необходимые компоненты: дистрибутив Tomcat 5.0.28 (можно 5.5.xx – процесс ничем не отличается), Apache HTTP server 2.0.59 + mod_jk.

Шаг 1. Разворачиваем первый Tomcat.
Выберите директорию для установки Tomcat серверов кластера. Разархивируйте первый дистрибутив. Запустите сервер и убедитесь, что все работает. Теперь у нас есть установленный Tomcat, на котором уже запущено несколько приложений. Работу кластера мы будем тестировать на примере приложения jsp-examples из дистрибутива.

Шаг второй. Настроим Apache HTTP + mod_jk.
Первый вопрос, который возникает на этом шаге: зачем _одному_ Tomcat’у (ведь кластера еще нет) нужен еще и Apache, если Tomcat и сам неплохо справляется с обработкой HTTP запросов? Ответ, который предоставляют разработчики, довольно неожиданный: Tomcat действительно неплохо работает с HTTP запросами, но в реальном мире, где на сервер сыплются тонны некорректных запросов и оборванных соединений – Apache справляется куда лучше. Второй нюанс: Tomcat все же написан на Java. Цена кроссплатформенности Java – это невозможность оптимизировать код под конкретную платформу. И снова-таки Apache лишен этого недостатка.
Таким образом в нашей архитектуре Apache HTTP server будет выступать в качестве “фильта” между пользователями и Tomcat серверами. На следующих шагах Apache будет выполнять еще и функцию распределителя нагрузки.

1. Установите Apache.
2. Запустите Apache и убедитесь что он работает: зайдите на http://localhost – там должна быть стартовая страничка Apache.
3. Скачайте mod_jk необходимой версии, переименуйте файл в mod_jk.so и поместите его в папку modules.
4. В файл httpd.conf добавляем такие строки:

LoadModule jk_module modules/mod_jk.so

# Path to workers.properties
JkWorkersFile conf/workers.properties

# Path to jk logs
JkLogFile logs/mod_jk.log

# Jk log level [debug/error/info]
JkLogLevel info

# Jk log format
JkLogStampFormat \"[%a %b %d %H:%M:%S %Y] \"

# JkOptions for forwarding
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

# JkRequestLogFormat set the request format
JkRequestLogFormat \"%w %V %T\"

JkMount /jsp-examples alpha
JkMount /jsp-examples/* alpha

5. В папке conf создаем файл workers.properties. Содержимое этого файла будет таким:


workers.tomcat_home=C:/apps/cluster/alpha
workers.java_home=C:/apps/jdk1.5.0_11

worker.list=alpha

worker.alpha.port=8009
worker.alpha.host=localhost
worker.alpha.type=ajp13
Естественно, вместо указанных путей укажите собственные.
Теперь поправим конфигурацию Tomcat:

6. Убедимся, что AJP коннектор настроен именно так:

\"8009\"

 enableLookups=\"false\" redirectPort=\"8443\" debug=\"0\"
 protocol=\"AJP/1.3\" />

7. Перезагружаем Tomcat и Apache. Убедимся, что все работает так как надо:
Если в браузере набрать http://localhost/jsp-examples/ - должна отобразиться страница с примерами jsp из дистрибутива Tomcat. Если страничка есть - значит все работает.
Поздравляю, теперь обработкой HTTP запросов занимается Apache.

Шаг третий. Добавим в кластер еще один сервер и настроим балансировку нагрузки.

1. Разархивируем еще один дистрибутив Tomcat.
2. В server.xml поправим конфигурацию так, чтобы не было конфликтов портов:

\"8006\" shutdown=\"SHUTDOWN\" debug=\"0\">
...

  \"8081\"
        maxThreads=\"150\" minSpareThreads=\"25\" maxSpareThreads=\"75\"
        enableLookups=\"false\" redirectPort=\"8443\" acceptCount=\"100\"
        debug=\"0\" connectionTimeout=\"20000\"
        disableUploadTimeout=\"true\" />
...

  \"8010\"
        enableLookups=\"false\" redirectPort=\"8443\" debug=\"0\"
        protocol=\"AJP/1.3\" />
...
3. Поправим workers.properties, чтобы нагрузка баллансировалась между двумя нодами:


workers.tomcat_home=C:/apps/cluster/alpha

workers.java_home=C:/apps/jdk1.5.0_11

worker.list=balancer

worker.alpha.port=8009
worker.alpha.host=localhost
worker.alpha.type=ajp13
worker.alpha.lbfactor=1

worker.bravo.port=8010
worker.bravo.host=localhost
worker.bravo.type=ajp13
worker.bravo.lbfactor=1

worker.balancer.type=lb
worker.balancer.balance_workers=alpha,bravo
4. Поправим httpd.conf:


JkMount /jsp-examples balancer
JkMount /jsp-examples/* balancer

5. Чтобы понимать, на какую ноду мы попали, поправим файлы webapps\\jsp-examples\\index.html в обеих нодах. В первой ноде добавим строку \"Alpha\", а во второй \"Bravo\". Теперь будет видно, какой из серверов в действительно обрабатывает запрос.

5. Запустим только что установленный Tomcat (теперь работает две ноды).
6. Перезапустим Apache.
7. Набираем в браузере http://localhost/jsp-examples/
8. Смотрим, какая нода обрабатывает наш запрос и останавливаем соответствующий Tomcat.
9. Обновляем страницу в браузере - теперь запрос обрабатывает другая нода (и никаких 404 :-))

Только что мы проимитировали ситуацию, когда одна из нод кластера перестала функционировать. Как видно - переключение на работающую ноду прошло абсолютно прозрачно для пользователя (если бы не надписи \"Alpha\" и \"Bravo\" пользователь даже не узнал-бы о переключении).

Шаг четвертый. Настаиваем репликацию сессий.

При существующей архитектуре, данные сессии пользователя при крахе ноды будут утеряны. Это далеко не всегда допустимо. На этом шаге мы настроим репликацию сессий: Tomcat ноды будут обмениваться данными о сессиях. Таким образом, если одна из нод упадет - копии сессии останутся на остальных нодах и пользователь сможет продолжить нормально работать.
На данном этапе элементы кластера не знают о существовании друг-друга. Фактически, все что надо сделать для репликации сессий это \"познакомить\" их.

К сожалению, в комплекте примеров jsp нет страниц, которые демонстрируют использование сессий. Поэтому прийдется немного повозиться, чтобы получить возможность проверить репликацию.

Создадим страничку session.jsp с таким содержанием:




 \"Content-Type\" content=\"text/html; charset=windows-1251\">
 


 
 



Для ноды bravo создадим точно такую же страницу, только вместо alpha будем устанавливать строку \"bravo\".

1. Убедимся, что сейчас репликация сессий не работает:
1.1. Зайдем на http://localhost/jsp-examples/session.jsp, заметим, какая нода обработала запрос.
1.2. Остановим соответствующую ноду.
1.3. Обновим в браузере страницу: как видно, вторая нода понятия не имеет о том, какие объекты добавляла в сессию первая нода.
1.4. Остановим обе ноды.

Теперь, собственно, репликация.

1. В server.xml для ноды alpha прописываем

\"Catalina\" defaultHost=\"localhost\" debug=\"0\" jvmRoute=\"alpha\">
2. В server.xml для ноды bravo прописываем

\"Catalina\" defaultHost=\"localhost\" debug=\"0\" jvmRoute=\"bravo\">
2. Раскомментируем блок Cluster нод alpha и bravo

3. В блоке Cluster ноды alpha устанавливаем


      \"org.apache.catalina.cluster.mcast.McastService\"
        mcastAddr=\"228.0.0.4\"
    mcastBindAddress=\"127.0.0.1\"
        mcastPort=\"45564\"
        mcastFrequency=\"500\"
        mcastDropTime=\"3000\"/>
   \"org.apache.catalina.cluster.tcp.ReplicationListener\"
        tcpListenAddress=\"auto\"
        tcpListenPort=\"4001\"
        tcpSelectorTimeout=\"100\"
        tcpThreadCount=\"6\"/>
4. Аналогично для bravo

\"org.apache.catalina.cluster.mcast.McastService\"
        mcastAddr=\"228.0.0.4\"
    mcastBindAddress=\"127.0.0.1\"
        mcastPort=\"45564\"
        mcastFrequency=\"500\"
        mcastDropTime=\"3000\"/>

   \"org.apache.catalina.cluster.tcp.ReplicationListener\"
        tcpListenAddress=\"auto\"
        tcpListenPort=\"4002\"
        tcpSelectorTimeout=\"100\"
        tcpThreadCount=\"6\"/>
5. В web.xml приложения jsp-examples обеих нод добавляем параметр :


\"http://java.sun.com/xml/ns/j2ee\"
  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
  xsi:schemaLocation=\"http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd\"
  version=\"2.4\">

 

  
   JSP 2.0 Examples.
  

 ...
 ...
5. Повторяем тест на репликацию описанный выше. Теперь, при переходе между нодами, данные из сессии пользователя не будут утеряны.

Заключение.

В этой заметке описан способ настройки кластера Tomcat серверов. Мы использовали HTTP сервер Apache для обработки HTTP запросов и для баллансировки нагрузки между серверами.

Для того чтобы добавить в кластер новую ноду необходимо сделать следующее:

1. Разархивировать дистрибутив tomcat.
2. В server.xml указать


\"xxxx\" shutdown=\"SHUTDOWN\" debug=\"0\">
тут xxxx - значение порта, которое не будет конфликтовать с другими портами кластера

3. Поправляем http коннектор


  \"xxxx\"
        maxThreads=\"150\" minSpareThreads=\"25\" maxSpareThreads=\"75\"
        enableLookups=\"false\" redirectPort=\"8443\" acceptCount=\"100\"
        debug=\"0\" connectionTimeout=\"20000\"
        disableUploadTimeout=\"true\" />
тут xxxx - значение порта, которое не будет конфликтовать с другими портами кластера

4. Указать параметры AJP коннектора:


  \"yyyy\"
        enableLookups=\"false\" redirectPort=\"8443\" debug=\"0\"
        protocol=\"AJP/1.3\" />
yyyy - аналогично

5. Указать значение jvmRoute для Catalina


\"Catalina\" defaultHost=\"localhost\" debug=\"0\" jvmRoute=\"myNextNode\">
значение jvmRoute должно быть уникальным для каждой ноды кластера.

6. Раскомментировать блок Cluster и в нем настроить


      \"org.apache.catalina.cluster.mcast.McastService\"
        mcastAddr=\"228.0.0.4\"
    mcastBindAddress=\"127.0.0.1\"
        mcastPort=\"45564\"
        mcastFrequency=\"500\"
        mcastDropTime=\"3000\"/>

   \"org.apache.catalina.cluster.tcp.ReplicationListener\"
        tcpListenAddress=\"auto\"
        tcpListenPort=\"zzzz\"
        tcpSelectorTimeout=\"100\"
        tcpThreadCount=\"6\"/>

zzzz - аналогично предыдущим.

В workers.properties добавить описание worker'a для новой ноды

worker.myNextNode.port=yyyy
worker.myNextNode.host=localhost
worker.myNextNode.type=ajp13
worker.myNextNode.lbfactor=1
...
worker.balancer.balance_workers=alpha,bravo,myNextNode
В результате мы получили кластер с баллансировщиком нагрузки, который относительно легко расширяется и который умеет передавать данные сессий между нодами.

Лично мне не удалость настроить для кластера Tomcat серверов Deployment Farm - замечательная возможность кластера, которая позволяет поставлять обновленное приложение одновременно на весь кластер.

Второй нюанс - кластером нельзя управлять динамически: поменяв workers.properties необходимо перезагрузить Apache.

А в остальном - довольно неплохо. Счастливой кластеризации.

* This source code was highlighted with Source Code Highlighter.

Метки:  

md5() + соль. Хранение паролей в базе данных

Четверг, 06 Декабря 2012 г. 15:51 + в цитатник
md5() + соль. Хранение паролей в базе данных

http://ekimoff.ru/74/

1) поле salt для хранения соли
2) поле password для хранения хеша от md5(md5(пароль)+соль) .



// $user – информация о пользователе из таблицы user
if (md5(md5($_POST['password']).$user['salt']) == $user['password']) {
// проверка прошла успешно. логиним!
}

function generateSalt() {
$salt = '';
$length = rand(5,10); // длина соли (от 5 до 10 сомволов)
for($i=0; $i<$length; $i++) {
$salt .= chr(rand(33,126)); // символ из ASCII-table
}
return $salt;
}


Метки:  

ИНСТАЛЯЦИЯ GLASSFISH 3.0.1 НА УБУНТУ

Среда, 05 Декабря 2012 г. 22:17 + в цитатник

Метки:  

Как развернуть сайт на весь экран

Вторник, 04 Декабря 2012 г. 13:12 + в цитатник
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<html>
  <header>
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    
    <style type="text/css">
      
      body
      {
        background: #fff;
        color: #000;
      }
      
    </style>
  </header>
<body>
<h2>Hello World!</h2>
<a href="#">Развернуть страницу</a>
   <script type="text/javascript">
      $('a').click(function () {
      
        var element = document.body;
        var req = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen;
       
        if(req){
          console.log(req);
          req.call(element);
        }
        else
        {
          var wscript = new ActiveXObject("Wscript.shell");
          wscript.SendKeys("{F11}");
        }
        
        return false;
      
      });
    </script>
</body>
</html>

* This source code was highlighted with Source Code Highlighter.

Метки:  

netbeans add jetty

Понедельник, 03 Декабря 2012 г. 15:11 + в цитатник



Метки:  

javascript date time format

Понедельник, 03 Декабря 2012 г. 13:35 + в цитатник
http://code.google.com/p/datejs/wiki/FormatSpecifiers



Date.parse('10:30 PM EST')   // Wed Oct 31 2007 20:30:00
Date.parse('10PM')       // Wed Oct 31 2007 22:00:00


* This source code was highlighted with Source Code Highlighter.


Русская локаль :


date-ru-RU.js

формат
//var dateTimePattern = "dd.MM.yyyy HH:mm";

Метки:  

Class IOUtils

Четверг, 29 Ноября 2012 г. 12:02 + в цитатник
URL url = null;
OutputStream r = new PrintStream(system.out);

url = new URL("http","host","port", "fileurl")

IOUtils.copy(u.openStream(),r);


http://commons.apache.org/io/apidocs/org/apache/commons/io/IOUtils.html

закрыть поток быстрее можно так

IOUtils.closeQuietly(in);

Быстрый способ копирования :

IOUtils.copy(in ,out);

Метки:  

jquery UML

Четверг, 29 Ноября 2012 г. 10:19 + в цитатник
получить картинки из таблицы html :

$(".UmlTableRow").eq(0).children().each(function(index,elem){console.log($(elem).first().children().attr("src"))})

* This source code was highlighted with Source Code Highlighter.



<table class="UmlTable" border="0" cellspacing="0" cellpadding="0">
<tbody><tr class="UmlTableRow">
<td class="UmlTableCell"><img src="overview0W0H0.png" width="502" height="516" usemap="#umlmap155W0H0" border="0"></td>
<td class="UmlTableCell"><img src="overview0W1H0.png" width="502" height="516" usemap="#umlmap155W1H0" border="0"></td>
<td class="UmlTableCell"><img src="overview0W2H0.png" width="501" height="516" usemap="#umlmap155W2H0" border="0"></td>
<td class="UmlTableCell"><img src="overview0W3H0.png" width="501" height="516" usemap="#umlmap155W3H0" border="0"></td>
</tr>
</tbody></table>


* This source code was highlighted with Source Code Highlighter.

Метки:  

utf-8 to cp866

Среда, 28 Ноября 2012 г. 23:11 + в цитатник
    char[] chars = {'Z', 'Я', 'œ'};
    Charset cp866 = Charset.forName("Cp866");
    CharsetEncoder cp866Encoder = cp866.newEncoder();
    for (char c : chars) {
      logger.info("{} {}",
            c,
            cp866Encoder.canEncode(c) ? "supported" : "not supported");
    }


* This source code was highlighted with Source Code Highlighter.

Метки:  

Distributed MVC Application model

Среда, 28 Ноября 2012 г. 17:36 + в цитатник
Distributed MVC Application model

Planet implements a distributed version of the Model-View-Controller Pattern (MVC). In this pattern, a web request starts in a Controller, which calls one more Services fetching Models (usually stored in databases), which is used by Templates (View) to render the web response.

http://www.planetframework.com/documentation/1.8/D...ributed-MVC-Application-model/


Distributed Command Pattern - an extension of command pattern for connected systems


The problem of distributed systems

While designing the architecture of connected systems, the design needs to consider how commands are executed not only in the application where it originated, but also on all other connected systems. For example, in a chat application which is connected to a chat room, if one user writes a message, the message needs to be shown on the user’s screen and also simultaneously on screens of all other users who are present on the chat room. This raises an architectural design issue where a command needs to be invoked on the originating application and necessary data be sent to the server in order to broadcast the message to all other connected users. Each connected user needs to receive the data from server, translate it, and then show it on the screen.

This situation results in extra architectural design and coding for the communication performed for each action. First of all, following the command pattern, we can only perform action on the same application, more specifically, on the same process. Then we need to prepare for a network transmission. So, there is some specific protocol developed to maintain communication with the server and the client. Both the server and the client maintain a code base to understand this protocol. When a message is received from the network, the message needs to be processed and then some specific code needs to be written in order to perform actions based on the message.

Here is a design which shows how a typical chat application is developed:


http://www.codeproject.com/Articles/9415/Distribut...Pattern-an-extension-of-comman

Метки:  

Fixing SQLDeveloper MSVCR71.DLL Not Found Error

Среда, 28 Ноября 2012 г. 14:32 + в цитатник
http://bigsnowball.com/content/fixing-sqldeveloper-msvcr71dll-not-found-error

To fix it, properly, you need to install SQLDeveloper yourself. Fortunately, this is simple.

Run regedit as the Administrator
Expand HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
Add a new Key to App Paths called sqldeveloper.exe
Set the (Default) value to the full path to the executable (including the executable name).
Create a new String value for sqldeveloper.exe called Path and set its value to the jre / bin folder in the SQLDeveloper files.
And here’s what it looks like:



def : C:\Program Files (x86)\sqldeveloper\sqldeveloper.exe

Path: C:\Program Files (x86)\sqldeveloper\jdk\jre\bin

Метки:  

Java Interceptors (в EJB 3.0)

Среда, 28 Ноября 2012 г. 14:02 + в цитатник
Java Interceptors (в EJB 3.0)

http://habrahabr.ru/post/146753/

public class SimpleLogger{
  @AroundInvoke
  public Object addLog(InvocationContext context){
    //какая-то логика логирования
  return context.proceed();
}


public class Summ {
  @Interceptors (SimpleLogger.class)
   public double getResult(){
      //логика
   }
}


public interface InvocationContext {
   public Object getTarget();
   public Method getMethod();
   public Object
   public void setParametrs(Object
   public java.util.Map<String,Object> getContextData();
   public Object proceed();
}



public class SimpleLogger{

  @PostConstruct
  public void init(InvocationContext context){
     //логирование создания объекта, например через context.getTarget()
     context.proceed():
  }
  
  @PreDestroy
  public void remove(InvocationContext context){
     //какая-то логика
  context.proceed():
  }
}



<interceptor-binding>
   <ejb-name>*<ejb-name>
   <interceptor-class> ru.interceptortest.Validate</interceptor-class>
</interceptor-binding>



public class SimpleLogger {
  
  @AroundInvoke
  public Object logAction(InvocationContext context) throws Exception {
    System.out.println("object - " + context.getTarget().getClass());
    System.out.println( "method - " + context.getMethod());   
    return context.proceed();
  }
  
}



@Stateless
public class Count implements Serializable{
  
  double firstArgument=0;
  double secondArgument=0;

//геттеры и сеттеры и тд  

  @Interceptors(SimpleLogger.class)
  public double getSummResult() {
    return getFirstArgument()+ getSecondArgument();
  }
  
}




public class LifeLogger {  
  
  @AroundInvoke
  public Object logAll(InvocationContext context) throws Exception {
    System.out.println("LogAll object - " + context.getTarget());
    System.out.println("LogAll method - " + context.getMethod());   
    
    return context.proceed();
  }
  
  @PostConstruct
  public Object logCreate(InvocationContext context) throws Exception {
    System.out.println("create - " + context.getTarget().getClass().getClass);  
    
    return context.proceed();
  }
  
}


* This source code was highlighted with Source Code Highlighter.



Представьте себе, что вы уже написали немалую часть кода приложения, и тут выясняется, что вам необходимо добавить логирование на вызов большого числа методов, или необходимо на некоторые схожие методы добавить дополнительную валидацию входных данных.
Вы можете просто переписать нужные участки кода, а можете воспользоваться появившемся в EJB 3.0 механизмом интерсепторов (interceptors).

Если интересны подробности и небольшой пример реализации прошу под кат.



Интерсепторы перехватывают вызовы методов бинов для выполнения определенных действий перед методом. Подобная концепция похожа filter chain у сервлетов.

Начнем рассмотрение с простого примера.
Для использования интерсептора сначала определим сам класс, с методом, который будет перехватывать вызовы.Пусть это будет простой логгер.

public class SimpleLogger{
@AroundInvoke
public Object addLog(InvocationContext context){
//какая-то логика логирования
return context.proceed();
}

Перехватывающий метод должен быть помечен аннотацией @AroundInvoke, позже подробнее рассмотрим его свойства.

Теперь для перехвата вызова нужного нам метода достаточно только добавить ему аннотацию с указанием нужного интерсептора. Например так:

public class Summ {
@Interceptors (SimpleLogger.class)
public double getResult(){
//логика
}
}

В данном примере когда кто-либо вызывает метод getResult класса Summ, то перед его выполнением сначала происходит выполнение метода addLog класса SimpleLogger, после чего он возвращает выполнение методу getResult.

Для начала рассмотрим перехватывающий метод.
Он обязан иметь аннотацию @AroundInvoke, и в классе интерцепорта может быть только один метод с этой аннотацией.
Этот метод может иметь модификатор доступа public, private protected или пакетного доступа, но не может быть объявлен как final или static
Семантика аннотированного метода должна удовлетворять следующему шаблону:
Object <имя метода> (InvocationContext <имя переменной>) throws Exception.

После выполнения действий внутри перехватывающего метода он возвращает выполнение бизнес методу или другому интерсептору в цепочке вызовом context.proceed(). Но, если не выполнить этот вызов, то никому не будет переданно выполнение, это может быть полезно, например при организации интерсептора с валидацией данных, если валидация не прошла, то продолжить выполнения не нужно.

Интерфейс InvocationContext позволяет нам получить доступ к информации о вызываемом методе.
Рассмотрим его код.

public interface InvocationContext {
public Object getTarget();
public Method getMethod();
public Object
public void setParametrs(Object
public java.util.Map getContextData();
public Object proceed();
}

getTarget возвращает объект, в котором был вызван перехваченный метод
getMethod возвращает метод бина, у которого был вызван интерсептор, но если был перехвачен жизненного цикла бина (например метод @PreDestroy), то он вернет null
getParametrs вернет входные параметры метода в виде массива объектов
setParametrs позволяет изменить в процессе выполнения параметры метода
getContextData возвращает карту, которая может быть использована интерсепторами для взаимодействия друг с другом, то есть, если один метод перехватывает несколькими интерсепторами, то первый может записать в эту карту какой-либо значение, а последующие интерсепторы для своих целей могут считать эти значения.


Так же можно перехватить callback методы жизненного цикла перехватываемого бина, для этого необходимо добавить соответствующие методы в класс интерсептора. Например так:

public class SimpleLogger{

@PostConstruct
public void init(InvocationContext context){
//логирование создания объекта, например через context.getTarget()
context.proceed():
}

@PreDestroy
public void remove(InvocationContext context){
//какая-то логика
context.proceed():
}
}

Еще одним особенным применением интерсепторов является то, что вы можете объявить так называемый “default interceptor” действие которого будет расспространятся на все классы внутри одного приложения. Такой перехватчик можно объявить только через дескриптор развертывания, выглядит это так


*
ru.interceptortest.Validate


При этом, если необходимо, что бы действие этого интерсептора не расспростанялось на какой-либо класс, его необходимо пометить его аннотаций @ExcludeDefaultInterceptors.

Попробуем написать простой пример с ипользованием интерсептора. Сначала создадим классы интерсепторов.
Сделаем самый простой класс, выводящий сообщения в консоль сервера, когда вызывается перехватываемый метод.

public class SimpleLogger {

@AroundInvoke
public Object logAction(InvocationContext context) throws Exception {
System.out.println("object - " + context.getTarget().getClass());
System.out.println( "method - " + context.getMethod());
return context.proceed();
}

}

И создадим простой класс, производящий арифметические операции, пометив один из методов аннотацией @Interceptors(SimpleLogger.class).

@Stateless
public class Count implements Serializable{

double firstArgument=0;
double secondArgument=0;

//геттеры и сеттеры и тд

@Interceptors(SimpleLogger.class)
public double getSummResult() {
return getFirstArgument()+ getSecondArgument();
}

}

Если вы будем вызывать метод этого класса getSummResult(), то в консоль сервера impleLogger.logAction выведет:

object - class ru.interceptorexample.Count
method - public double ru.interceptorexample.Count.getSummResult()

Добавим еще один класс интерсептора.

public class LifeLogger {

@AroundInvoke
public Object logAll(InvocationContext context) throws Exception {
System.out.println("LogAll object - " + context.getTarget());
System.out.println("LogAll method - " + context.getMethod());

return context.proceed();
}

@PostConstruct
public Object logCreate(InvocationContext context) throws Exception {
System.out.println("create - " + context.getTarget().getClass().getClass);

return context.proceed();
}

}

И добавим еще один метод в класс Count.

public double getMultiplyResult(){
return getFirstArgument() * getSecondArgument();
}

И пометим дополнительно весь класс аннотацией @Interceptors(LifeLogger.class).
Теперь, когда будет вызван метод getMultiplyResult, сначала, при создании экземпляра класса Count, интерсептор LifeLogger выведет в консоль сервера:

create - class ru.interceptorexample.Count

а потом:

LogAll object - class ru.interceptorexample.Count
LogAll method - public double ru.interceptorexample.Count.getMultiplyResult()

А если вызывать метод getSummResult то сначала отработает интерсептор LifeLogger, а потом SimpleLogger и в консоли сервера получится:

LogAll object - class ru.interceptorexample.Count
LogAll method - public double ru.interceptorexample.Count.getSummResult()
object - class ru.interceptorexample.Count
method - public double ru.interceptorexample.Count.getSummResult()

Очевидно, что для практических задач вывод с консоль целесообразно было бы заменить на нормальное логирование, например использоваться log4j, но я надеюсь данных примеров было достаточно для того что бы понять как работает механизм интерсепторов.

Источники информации, для тех, кто хочет подробнее узнать работу этого механизма:
1. мануалы с сайта oracle.com
2. EJB 3 in Action — Debu Panda, Reza Rahman, Derek Lane ISBN: 1-933988-34-7

Исходные коды в виде маленького простого веб приложения желающие могут получить с гитхаба (проект делал под netbeans и glassfish, но думаю не составит труда, если понадобится перенести его в другую среду). github.com/tsegorah/JavaInterceptorsExample.git

Метки:  

mysql rownum

Среда, 28 Ноября 2012 г. 11:11 + в цитатник
SELECT @rownum:=@rownum+1 rank, p.id , p.message_text FROM MESSAGE p, (SELECT @rownum:=0) r ORDER BY create_date DESC LIMIT 10;

* This source code was highlighted with Source Code Highlighter.

Метки:  

java call pl sql

Вторник, 27 Ноября 2012 г. 23:03 + в цитатник
Calling PL/SQL from Java

Java Database Connectivity (JDBC) and SQLJ enable you to call PL/SQL stored functions and procedures. For example, you want to call the following stored function, which returns the balance of a specified bank account:

FUNCTION balance (acct_id NUMBER) RETURN NUMBER IS
acct_bal NUMBER;
BEGIN
SELECT bal INTO acct_bal FROM accts
WHERE acct_no = acct_id;
RETURN acct_bal;
END;
In a JDBC program, a call to the balance function can be written as follows:

...
CallableStatement cstmt = conn.prepareCall("{? = CALL balance(?)}");
cstmt.registerOutParameter(1, Types.FLOAT);
cstmt.setInt(2, acctNo);
cstmt.executeUpdate();
float acctBal = cstmt.getFloat(1);
...
In a SQLJ program, the call can be written as follows:

...
#sql acctBal = {VALUES(balance(:IN acctNo))};
...


* This source code was highlighted with Source Code Highlighter.

Метки:  

Java запись в две связанные таблицы

Вторник, 27 Ноября 2012 г. 16:14 + в цитатник
...
try {
    con.setAutoCommit(false);
    PreparedStatement stmt= null;
...
// вставка в первую таблицу
...
// получили id вставленной записи
...
// вставка во ворую таблицу
//таблица с автоинкрементом по id
...
} catch (SQLException e ) {

    if (con != null) {
        System.err.print("Transaction is being rolled back");
        con.rollback();
    }
} finally {
    if (stmt!= null) {
      stmt.close();
    }
    con.setAutoCommit(true);
  }
...



если записей которые нужно вставить в таблицу B

1000 или больше - как организовать их вставку - отдельными командами insert -

после каждой делать
statement.addBatch();
после каждой 100 делать
statement.executeBatch();


// вставка в первую таблицу
connection = database.getConnection();
connection.setAutoCommit(false);

PreparedStatement stmt = null;
ResultSet rs = null;
//таблица с автоинкрементом по id
stmt = con.prepareStatement("INSERT INTO tableA (message_text) VALUES (?)");
stmt.setString(1, msg);
stmt.execute();
      
int autoIncKeyFromFunc = -1;
rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");
// получили id вставленной записи
      if (rs.next()) {
        autoIncKeyFromFunc = rs.getInt(1);
}


// вставка во ворую таблицу
//таблица с автоинкрементом по id

List<Integer> usersId = new ArrayList<Ineger>();
usersId.add(1);
usersId.add(2);
usersId.add(3);


PreparedStatement updateTotal = connection.prepareStatement("insert into B (id_a, id_t) values (? ,?) ");

for(List userId :usersId ){
updateTotal .setInt(1, autoIncKeyFromFunc);
updateTotal .setInt(2, usersId.get(i));
//stmt.execute();
updateTotal .addBatch();
updateTotal .executeBatch();
}
updateTotal.execute();
con.commit();


* This source code was highlighted with Source Code Highlighter.

Метки:  

ubuntu netbeans look and feel + font

Воскресенье, 25 Ноября 2012 г. 22:34 + в цитатник

Метки:  

боремся с тем что натворил троян

Воскресенье, 25 Ноября 2012 г. 21:44 + в цитатник
Для этого Вам необходимо создать текстовый документ и вставить в него нижеприведенный код, после чего сохранить и изменить расширение файла на .bat, далее просто запускаем.

@echo off
mode con codepage select=1251 > nul
echo Please wait...
attrib -s -h -r -a /s /d


Он снимает все атрибуты со всех папок и файлов.

Далее создаем в корне флешки папку autorun.inf - делаем ее скрытой и архивной и создаем в ней папку

cmd - > переходим на этот диск -> открываем папку autorun.inf - в cmd-> md name..\

для самых ленивых - можно создать файл с именем null - это устройство в виндоус и его вирус удалить не сможет

Метки:  

тестирование jmeter

Суббота, 24 Ноября 2012 г. 22:07 + в цитатник

Метки:  

java compiler

Суббота, 24 Ноября 2012 г. 17:57 + в цитатник
http://forum.vingrad.ru/topic-169769.html#st_0_view_0


public class TestClass{
  public void ptest(){
    System.out.println("It works! "+this.toString());
  }
}


import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
class SomeLoader extends ClassLoader{
  /*
   * зараза нихатит создавать объекты класса ClassLoader,
   * т.к. у того нет публик конструкторов
   * поэтому будем создавать объекты этого класса
   */
}
public class Test{
  public static void main(String[]args){
    //это список файлов для компиляции
    ArrayList<String> files1 = new ArrayList<String>();
    files1.add("TestClass.java");
    
    //получаем стандартный JIT компилятор и файловый менеджер
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    
    
    //получаем список чего-то, наследующего JavaFileObject
    //список можно получать как из коллекции имен файлов, так и собстно файлов
    Iterable<? extends JavaFileObject> compilationUnits1 =
      fileManager.getJavaFileObjectsFromStrings(files1);
    
    
    //получили задачу для компилятора и запустили его на выполнение
    //в итоге в текущем каталоге будет создан TestClass.class
    compiler.getTask(null, fileManager, null, null, null, compilationUnits1).call();
    
    try {
      fileManager.close();
      
      ClassLoader l = new SomeLoader();
      Class<?> clazz = l.loadClass("TestClass");
      //следующие две строки задают массив параметров (в нашем случае пустых)
      Class<?> cl[]=null;
      Object ob[]=null;
      Method ptest = clazz.getMethod("ptest", cl);
      Object o = clazz.newInstance();
      //ну и соссно вызываем метод, определенный в нашем классе
      ptest.invoke(o, ob);
      
    }catch(IOException e){
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (SecurityException e) {
      e.printStackTrace();
    } catch (NoSuchMethodException e) {
      e.printStackTrace();
    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      e.printStackTrace();
    }
    
  }
}

* This source code was highlighted with Source Code Highlighter.

java db connector

Пятница, 23 Ноября 2012 г. 00:08 + в цитатник
разными способами
...

NetBeans 7.0 and 7.1 UML plugin

Вторник, 13 Ноября 2012 г. 17:16 + в цитатник
NetBeans 7.0 and 7.1 UML plugin
If you are using NetBeans 7.0 or 7.1, you probably can't find your UML plugin any more in the default repository.

From what I can read on the net, the team is working on the plugin rewriting it, and this will take a while.


Semi-broken solution
There is another way to install it, but beware, the plugin will be semi-broken, so jump down to another solution if you like to generate a pretty UML diagram from your code:
by the menu navigate to Tools -> Plugins;
select the "Settings" tab;
click the "Add" button;
as URL copy the following into the textbox:
http://dlc.sun.com.edgesuite.net/netbeans/updates/6.9/uc/m1/dev/catalog.xml
Now on the tab "Available Plugins" there should be UML in category UML.

Метки:  

Понравилось: 1 пользователю

Идея

Пятница, 21 Сентября 2012 г. 14:31 + в цитатник
Новая идея - для компаний производителей Пылесосов с камерами - выводить видео на сайт для удаленной уборки через интернет ...

как хозяев так и всех желающих

Метки:  

Подсчет количества уникальных в массиве

Среда, 12 Сентября 2012 г. 15:12 + в цитатник

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;

public class CountRepeatingElements {
public static  CountRepeatingElements algorithm = new CountRepeatingElements();

  
  public Map<Object, AtomicInteger> countRepeatingElements(Object... elements) {
    ConcurrentMap<Object, AtomicInteger> result = new ConcurrentHashMap<Object, AtomicInteger>();
    for (Object element : elements) {
      result.putIfAbsent(element, new AtomicInteger(0)); //useful method that exists only in concurrent maps
      result.get(element).incrementAndGet();
    }
    return result;
  }
  
  

  public Map<Object, AtomicInteger> testCountRepeatingElements() throws Exception {
    Map<Object, AtomicInteger> result = algorithm.countRepeatingElements("aaa", "bbb", "aaa", "ccc", "bbb", "aaa");
    return result;

  }
  public static void main(String[] args) throws Exception {
    Map<Object, AtomicInteger> result = algorithm.testCountRepeatingElements();
    Set<Object> keys = result.keySet();
    for (Object object : keys) {
      System.out.println(object + " = " + result.get(object) );
      
    }
  }
}

* This source code was highlighted with Source Code Highlighter.

Метки:  

Конкурс по ФП

Вторник, 11 Сентября 2012 г. 15:33 + в цитатник


import java.util.*;
import java.lang.*;
import java.io.FileNotFoundException;

class Main
{

  public static TreeSet<Integer> normals = new TreeSet<Integer>();
  public static TreeSet<Integer> mads = new TreeSet<Integer>();
  public static List<Person> allpersons = new ArrayList<Person>();
  public static List<Integer> listOfMad = new ArrayList<Integer>();
  
  
   private class Person {

    public Integer num;
    public String mChar;
    public TreeSet<Integer> list = new TreeSet<Integer>();
    public TreeSet<Integer> diagnoz = new TreeSet<Integer>();
    public boolean ismad;
    public boolean isnormal;

    public Person() {
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder();
      for (Integer integer : list) {
        sb.append(", ").append(integer);
      }
      String result = "[" + num + "] " + mChar + " " + sb.toString();
      return result;
    }

    public String printNote() {
      String result = "Суждения о других :";
      for (Integer integer : list) {
        result = result + " ," + integer;
      }

      return result;
    }

    public String printDiagnoz() {
      String result = "Суждения о Мне : ";
      for (Integer integer : diagnoz) {
        result += " ," + integer;
      }
      return result;
    }
  }
  
  
    public List<Person> readData() throws FileNotFoundException {
 
    Scanner fw = new Scanner(System.in);
    while (fw.hasNextLine()) {
      Person person = new Person();
      String str = fw.nextLine();
      String[] arr = str.split(": '");
      person.num = Integer.parseInt(arr[0].trim());
      arr = arr[1].split("',");
      person.mChar = arr[0];
      arr = arr[1].split(",");
      for (int i = 0; i < arr.length; i++) {
        try {
          person.list.add(Integer.parseInt(arr[i].trim()));
        } catch (NumberFormatException nfe) {
          System.out.println("error" + person.num);
        }
      }

      allpersons.add(person);
    }
    return allpersons;
  }
  
    public static int sign(Integer x) {
    return x > 0 ? 1 : -1;
  }

  public static void printDiagnoz(int mad) {
    int size = allpersons.size();
    Person ismad = allpersons.get(mad - 1);
    Integer madNum = ismad.num;
    for (int i = 0; i < size; i++) {
      Person next = allpersons.get(i);
      for (Integer integer : next.list) {
        if (madNum.equals(Math.abs(integer))) {
          ismad.diagnoz.add(sign(integer) * next.num);
          break;
        }
      }
    }
  }
  
    public static boolean findMad(Integer personId, Integer doctor) {
    Person person = allpersons.get(personId - 1);
    TreeSet<Integer> madlist = person.list;
    for (Integer integer : madlist) {
      if (integer > 0) {
        if (!listOfMad.contains(integer) && !integer.equals(doctor)) {
          listOfMad.add(integer);
          mads.add(integer);
        }
      } else {
        if (mads.contains(Math.abs(integer))) {
          return true;
        }
        normals.add(Math.abs(integer));
      }
    }
    return false;
  }
  
    public static void printPicture(int col) {
    int i = 0;
    System.out.println("");
    for (Integer integer : mads) {
      i++;
      if (i % col == 0) {
        System.out.println("");
      }
      System.out.print(allpersons.get(integer - 1).mChar);
    }
    List<Integer> list = new ArrayList<Integer>();
    list.addAll(normals);
    Collections.reverse(list);
    for (Integer integer : list) {
      i++;
      if (i % col == 0) {
        System.out.println("");
      }

      System.out.print(allpersons.get(integer - 1).mChar);
    }

  }
  
    public static void fillMass(Integer doctor, Integer mad) {

    int size = allpersons.size();
    mads.clear();
    normals.clear();
    mads.add(mad);

    listOfMad.clear();
    listOfMad.add(mad);

    for (int j = 0; j < listOfMad.size(); j++) {
      int mun = listOfMad.get(j);
      Person person = allpersons.get(mun - 1);
      TreeSet<Integer> madlist = person.list;
      for (Integer integer : madlist) {
        if (integer > 0) {
          if (!listOfMad.contains(integer) && !integer.equals(doctor)) {
            listOfMad.add(integer);
            mads.add(integer);
          }
        } else {
          normals.add(Math.abs(integer));
        }
      }
    }

  }
  
  
    public static void main (String[] args) throws java.lang.Exception
    {
    long time = System.currentTimeMillis();
    Main Fd = new Main();
    Fd.readData();

    int madd = 405;
    printDiagnoz(madd);
    

    Person ismad = allpersons.get(madd - 1);
    System.out.println(ismad.printDiagnoz());
    System.out.println(ismad.printNote());
//
    int size = allpersons.size();
    boolean isDoctor = false;
    int dictorId = -1;
    for (int i = 1; i <size; i++) {


      mads.clear();
      normals.clear();
      mads.add(madd);
      
       
      listOfMad.clear();
      listOfMad.add(madd);

      boolean isMad = false;
      for (int j = 0; j < listOfMad.size(); j++) {

        isMad = findMad(listOfMad.get(j), i);
        if (isMad || (mads.size() + normals.size()) > size) {
          if(isMad) {
            isDoctor = true;
            dictorId = listOfMad.get(j);
          
          }
          isMad = false;
          break;
        }

      }
      int sum = mads.size() + normals.size() + 1;
      if (!isMad && sum == size) {
        System.out.println(" doctor x: " + i);
        break;
      }
      if(isDoctor){
         System.out.println(" Doctor X: " +dictorId);
         break;
      }

    }

    System.out.print("time : " + (System.currentTimeMillis() - time) + " ms");
    fillMass(dictorId, madd);
    printPicture(31);
     mads.clear();
     normals.clear();
     listOfMad.clear();

    }
}


* This source code was highlighted with Source Code Highlighter.

Метки:  

javascript window.opener return json

Четверг, 06 Сентября 2012 г. 17:48 + в цитатник

Метки:  

Immunity Products

Пятница, 31 Августа 2012 г. 12:41 + в цитатник
Java 0day analysis (CVE-2012-4681)
(This post brought to you by Esteban, Immunity's in-house Java friend)
Summary
A couple of days ago, a Java 0day was found running like crazy in the wild. While a lot of defense bunnies where asking "WWMAD" (What will my Antivirus do?), we decide to dive into Java for the details of the vulnerability and as we expected, the unpatched vulnerabilities used in the Gondvv exploit were more than one (When we said, "dive deep into Java", we actually meant open our new Infiltrate 2013 Master Class slide deck which will include a full day of Java auditing).

The first bug was used to get a reference to sun.awt.SunToolkit class that is restricted to applets while the second bug invokes the getField public static method on SunToolkit using reflection with a trusted immediate caller bypassing a security check.

The beauty of this bug class is that it provides 100% reliability and is multiplatform. Hence this will shortly become the penetration test Swiss knife for the next couple of years (as did its older brother CVE-2008-5353).

As a final note, the bug was introduced in Java 7.0 released in July 28, 2011. While you are feeling the rush of blood going through your veins while by getting all those shell being pop, think that somewhere not far way (Probably a 10hs flight from some of the major airports in Norte Americana) was enjoying it non-stop for quite some time now.


http://immunityproducts.blogspot.com/2012/08/java-0day-analysis-cve-2012-4681.html

Метки:  

регулярные выражения regexp isURL

Четверг, 30 Августа 2012 г. 19:03 + в цитатник
    String regc = "((https?|ftp|file)://([a-zA-Z0-9+&@#%?=~_|!:,.;]*)([a-zA-Z0-9+&@#%?/=~_|!:,.;]*)[^ ])";
    String regx ="((https?|ftp|file)://[^ ]{3,})";
    String regb = "((ftp|http|https)://(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(/|/([\\w#!:.?+=&%@!\\-\\/]))?)";


* This source code was highlighted with Source Code Highlighter.

Метки:  

...

Среда, 29 Августа 2012 г. 10:54 + в цитатник
Магнитики из старых процессоров :)

Метки:  

Зеркало

Среда, 29 Августа 2012 г. 10:29 + в цитатник

Метки:  

скачать файлы из контакта

Вторник, 28 Августа 2012 г. 17:15 + в цитатник
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package vkphoto.english;

import java.io.File;
import java.io.FileWriter;
import java.net.URL;
import java.util.Scanner;
import org.json.JSONException;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.VkontakteApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;

/**
*
* @author isalnikov
*/
public class EnglishPhoto {

  /**
   * @param args the command line arguments
   */
   private static final String NETWORK_NAME = "Vkontakte.ru";
   //private static final String PROTECTED_RESOURCE_URL_GET = "https://api.vkontakte.ru/method/photos.get";
   private static final String PROTECTED_RESOURCE_URL_GET = "https://api.vkontakte.ru/method/photos.getAll";
 //  private static final String PROTECTED_RESOURCE_URL_GET = "https://api.vkontakte.ru/method/photos.getAlbums";
 
 
 
 private static final Token EMPTY_TOKEN = null;

 public static void main(String[] args) throws JSONException, Exception
 {
  final String clientId = "";
  final String apiSecret = "";
  
  OAuthService service = new ServiceBuilder()
                 .provider(VkontakteApi.class)
                 .apiKey(clientId)
                 .apiSecret(apiSecret)
                 .scope("notify,friends,wall,audio,notes,messages,offline,photos,groups") // replace with desired scope
                 .callback("http://api.vkontakte.ru/blank.html") //для приложения
                 .build();
  Scanner in = new Scanner(System.in);
  System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
  System.out.println();

  // Obtain the Authorization URL
  System.out.println("Fetching the Authorization URL...");
  String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
  System.out.println("Got the Authorization URL!");
  System.out.println("Now go and authorize Scribe here:");
  System.out.println(authorizationUrl);
  System.out.println("And paste the authorization code here");
  System.out.print(">>");
  Verifier verifier = new Verifier(in.nextLine());
  System.out.println();

  // Trade the Request Token and Verfier for the Access Token
  System.out.println("Trading the Request Token for an Access Token...");
  Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
  System.out.println("Got the Access Token!");
  System.out.println("(if your curious it looks like this: " + accessToken + " )");
  System.out.println();

  // Now let's go and ask for a protected resource!
  System.out.println("Now we're going to access a protected resource...");
  OAuthRequest request = null;
  request = new OAuthRequest(Verb.POST, PROTECTED_RESOURCE_URL_GET);
   
  //-36775085
   request.addBodyParameter("owner_id", "-36775085");
//   request.addBodyParameter("gid", "36775085");
//   request.addBodyParameter("aid", "158956214");
   request.addBodyParameter("count", "100");
   request.addBodyParameter("offset", "900");
  
  
//   request.addBodyParameter("aid", "161756102");
//   request.addBodyParameter("aid", "161750509");
//   request.addBodyParameter("aid", "161642875");
//   request.addBodyParameter("aid", "161642730");
//   request.addBodyParameter("aid", "156323580");
  
  
//   request.addBodyParameter("aid", "158956214");
//   request.addBodyParameter("aid", "158956214");
//  

  
//   request.addBodyParameter("filter", "owner");
//   request.addBodyParameter("filter", "owner");
  
  // HD   Иpинa Шeйк
  
 // request.addBodyParameter("count", "100");
// request.addBodyParameter("offset", "410");
  //gr
   //request.addBodyParameter("gid", "22786271");
  // request.addBodyParameter("aid", "140908579");
  
   
   service.signRequest(accessToken, request);
   Response response = null;
   response = request.send();
   
  System.out.println(response.getCode());
  System.out.println(response.getBody());
 
  NewMain.setResource(response.getBody());
 
}
}


* This source code was highlighted with Source Code Highlighter.

qsort

Понедельник, 27 Августа 2012 г. 15:59 + в цитатник
//алгоритм на языке java
 public static void qSort(int[] A, int low, int high) {
   int i = low;
   int j = high;
   int x = A[(low+high)/2];
   do {
     while(A[i] < x) ++i;
     while(A[j] > x) --j;
     if(i <= j){
       int temp = A[i];
       A[i] = A[j];
       A[j] = temp;
       i++; j--;
     }
   } while(i <= j);

   if(low < j) qSort(A, low, j);
   if(i < high) qSort(A, i, high);
 }


* This source code was highlighted with Source Code Highlighter.

Метки:  

netbeans gwt gxt

Понедельник, 13 Августа 2012 г. 17:46 + в цитатник

Метки:  

How to divide a number by 3 without using *, /, +, -, %, operators?

Понедельник, 30 Июля 2012 г. 16:55 + в цитатник

//java

  public static void main(String[] args) {
    // TODO code application logic here
    int a = divBy3(15003);
    System.out.println(a);
    
  }
  
  
  public static int divBy3(long a) {
    a <<= 30;
    for (int i = 2; i <= 32; i <<= 1) {
      a = add(a, a >> i);
    }
    return (int) (a >> 32);
  }

  public static long add(long a, long b) {
    long carry = (a & b) << 1;
    long sum = (a ^ b);
    return carry == 0 ? sum : add(carry, sum);
  }
}

//C++

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
int main() {
   FILE * fp=fopen("temp.dat","w+b");
   int number=12346;
   int divisor=3;
   char * buf = malloc(number);
   memset(buf,0,number);
   fwrite(buf,number,1,fp);
   rewind(fp);
   int result=fread(buf,divisor,number,fp);
   printf("%d / %d = %d", number, divisor, result);
   free(buf);
   fclose(fp);
   return 0;
}


* This source code was highlighted with Source Code Highlighter.

Метки:  

Задача лифты

Вторник, 10 Июля 2012 г. 11:24 + в цитатник
В восьмиэтажном супермаркете имеется два лифта, один — вместимостью два человека (в начальный момент времени находится на четвёртом этаже), второй рассчитан только на одного человека (находится на втором этаже).
Мужчина, что находится на втором этаже, сегодня идёт на свидание.
У женщины на пятом этаже есть сын, которому завтра исполнится семь лет.
Также на пятом этаже девочка только что выпросила у родителей денег на мороженое.
Мальчик, что находится на восьмом этаже, хочет поиграть в игровые автоматы.
Наконец, на седьмом этаже находится кошка Саши, которая жаждет вернуться домой.
За какое минимальное количество шагов лифты могут доставить людей и животных на требуемые этажи и что это за шаги, если известно, что:
Магазин игрушек находится на третьем этаже.
Кондитерские изделия продаются на шестом этаже.
Цветочный магазин находится на восьмом.
Игровые автоматы находятся прямо под магазином игрушек.
У кошки есть специальная бабушка, которая может нажать на кнопку требуемого этажа (и они вдвоём с кошкой занимают место одного человека в лифте).

code

Метки:  

javascript NaN

Среда, 27 Июня 2012 г. 15:13 + в цитатник
Чтобы избежать проблем со значением NaN я использую собственную функцию определения является ли переменная числом:


function isNum(v) {
return typeof v === 'number' && isFinite(v);
}


Метки:  

Нахождение пары ближайших точек

Понедельник, 18 Июня 2012 г. 18:33 + в цитатник
http://e-maxx.ru/algo/nearest_points

Даны точек на плоскости, заданные своими координатами . Требуется найти среди них такие две точки, расстояние между которыми минимально.

Метки:  

javascript прокрутка городов

Суббота, 28 Апреля 2012 г. 11:23 + в цитатник
javascript Карусель

потребовалось создать горизонтальную карусель для прокрутки городов !

Для java - ничего нет проще скажите Вы! - кольцевой двунаправленный список !

а что делать на javascript - первое что приходит в голову - создать аналогичную структуру похожую на LinkedList

но есть решение куда красивее , эффектнее и изящнее !

решение

Метки:  

LinkedList

Пятница, 27 Апреля 2012 г. 19:04 + в цитатник
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
    <title>JSP Page</title>
  </head>
  <body>
    
    <script>
      function LinkedList() {
        this._length = 0;
        this._head = null;
      }
      
      LinkedList.prototype = {

  add: function (data){

    //create a new node, place data in
    var node = {
        data: data,
        next: null
      },

      //used to traverse the structure
      current;

    //special case: no items in the list yet
    if (this._head === null){
      this._head = node;
    } else {
      current = this._head;

      while(current.next){
        current = current.next;
      }

      current.next = node;
    }

    //don't forget to update the count
    this._length++;

  },
   item: function(index){

    //check for out-of-bounds values
    if (index > -1 && index < this._length){
      var current = this._head,
        i = 0;

      while(i++ < index){
        current = current.next;
      }

      return current.data;
    } else {
      return null;
    }
  },
   remove: function(index){

    //check for out-of-bounds values
    if (index > -1 && index < this._length){

      var current = this._head,
        previous,
        i = 0;

      //special case: removing first item
      if (index === 0){
        this._head = current.next;
      } else {

        //find the right location
        while(i++ < index){
          previous = current;
          current = current.next;
        }

        //skip over the item to remove
        previous.next = current.next;
      }

      //decrement the length
      this._length--;

      //return the value
      return current.data;      

    } else {
      return null;
    }

  }

  //more methods here
};


var list = new LinkedList();
list.add("red");
list.add("orange");
list.add("yellow");

console.log(list.item(1));//"orange"
console.log(list.remove(1));
console.log(list.item(1));

   
    </script>
    
  </body>
</html>


* This source code was highlighted with Source Code Highlighter.

Метки:  

javascript cookie

Четверг, 12 Апреля 2012 г. 18:09 + в цитатник
Свойства кук:

NAME=VALUE - NAME-имя cookie, VALUE - значение.

expires=DATE - время хранения cookie, дата в формате "expires=Monday, DD-Mon-YYYY HH:MM:SS GMT", после которой истекает время хранения cookie. Если этот атрибут не указан, то cookie хранится в течение одного сеанса, до закрытия броузера.

domain=DOMAIN_NAME - домен, для которого значение cookie действительно. Например, "domain=javascript.ru". В этом случае значение cookie будет действительно и для домена javascript.ru, и для www.javascript.ru.
Если этот атрибут опущен, то по умолчанию используется доменное имя сервера, на котором было задано значение cookie.

path=PATH - этот атрибут устанавливает подмножество документов, для которых действительно значение cookie. Для того, чтобы cookie отсылались при каждом запросе к серверу, необходимо указать корневой каталог сервера, например, "path=/". Если этот атрибут не указан, то значение cookie распространяется только на документы в той же директории, что и документ, в котором было установлено значение cookie.

secure - если стоит этот маркер, то информация cookie пересылается только через HTTPS (HTTP с использованием SSL - Secure Socket Level), в защищенном режиме. Если этот маркер не указан, то информация пересылается обычным способом.

Библиотека для работы с куками:
function setCookie(name, value, expires, path, domain, secure) {
  if (!name || !value) return false;
  var str = name + '=' + encodeURIComponent(value);
  
  if (expires) str += '; expires=' + expires.toGMTString();
  if (path)  str += '; path=' + path;
  if (domain) str += '; domain=' + domain;
  if (secure) str += '; secure';
  
  document.cookie = str;
  return true;
}

function getCookie(name) {
  var pattern = "(?:; )?" + name + "=([^;]*);?";
  var regexp = new RegExp(pattern);
  
  if (regexp.test(document.cookie))
  return decodeURIComponent(RegExp["$1"]);
  
  return false;
}

function deleteCookie(name, path, domain) {
  setCookie(name, null, new Date(0), path, domain);
  return true;
}

* This source code was highlighted with Source Code Highlighter.

Метки:  

Поиск сообщений в ATUM
Страницы: 12 ... 7 6 [5] 4 3 ..
.. 1 Календарь