PHP

Cassandra y PHP para desarrolladores SQL: El modelo de datos

0

Si has trabajado con una base de datos relacional tal vez te resulte algo confuso al principio comprender el modelo de datos que usa Cassandra, intentaré ser lo más claro posible, pero si te surgen preguntas no dudes en dejarlas en los comentarios.

 

Columnas

El elemento más básico de la base de datos Cassandra es la columna, se compone de tres elementos: nombre de la columna, valor y timestamp. Os muestro un ejemplo como un array:

 array(
“nombre” => “email”,
“valor” => “webmaster@localhost.com”,

“timestamp” => time()

,

)

 

Super columnas

Es el conjunto de columnas con sus correspondientes valores:

array(
“nombre_superColumna” => array(

 

“usuario1″ => array(
“nombre” => “email”,
“valor” => “webmaster@localhost.com”,
“timestamp” => time()
),
“usuario2″ => array(
“nombre” => “email”,
“valor” => “email@email.com”,
“timestamp” => time()
),

 

“usuario3″ => array(
“nombre” => “email”,
“valor” => “otroemail@otroemail.com”,
“timestamp” => time()
),

),

)

 

Familia de columnas

Es el conjunto de columnas o super columnas. Me explico:

Las column Family o  familia de columnas se puede configurar de dos maneras: como Super o como Simple. Si se elige la opción Simple, en la column family solo se podrán guardar columnas no super columnas. En cambio si la column family está configurada como Super podrá guardar, además de las columnas, las super columnas. Esta flexibilidad permite jugar con la base de datos y adaptarla a nuestras necesidades.

Ejemplo:

 array(
“name” => “ColumnFamily”,
array( “name” => “SuperColumn”,
array( “colums” )
),
)

Keyspace

El keyspace es nuestra base de datos, donde alojaremos todas las columFamilies que necesitemos.

Ejemplo:

array(
“name” => “keyspace”,
array(“name” => “columnFamily”,
array(
[...]
),
),
)

Cassandra y PHP para desarrolladores SQL: Instalación

0

La base de datos No-SQL Cassandra fue creada por Facebook a causa de la necesidad de disponer de una base de datos distribuida de alto rendimiento, flexible, tolerante a fallos, escalable y que fuese capaz de procesar grandes cantidades de datos, más tarde fue liberada bajo licencia Apache y actualmente es utilizada principalmente por empresas de internet con proyectos con un alto uso de base de datos como Twitter.

En esta serie de artículos iré desgranando la instalación, funcionamiento y desarrollo de aplicaciones en PHP con Cassandra, comparando las sentencias utilizadas para insertar, actualizar, etc de SQL con los métodos a utilizar en Cassandra. Por desgracia al ser algo completamente distinto a cualquier base de datos SQL tendré que añadir algo de teoría, pero intentaré que os resulte lo más ameno posible.

Al toro.

 

 

REQUISITOS

Para la realización de esta guía se utilizará Debian Squeeze como sistema operativo. En algunos de los links que dejo como bibliografía al final del artículo existen ejemplos para realizar la instalación en otros sistemas operativos, principalmente CentOS.

Doy por hecho que ya se dispone de un servidor web Apache con PHP instalado en la máquina de testeo que se esté usando. Las aplicaciones que se van a instalar han sido probadas en una máquina virtual Debian utilizando como aplicación de virtualización, VirtualBox instalado en un host Windows XP SP3.

En un servidor de producción recomiendo que tenga bastante RAM (por encima de 1GB, ya veremos más adelante el porqué. En la máquina virtual que uso de testeo dispone de 700 MB y funciona bien, pero en producción no es lo recomendable).

Instalaremos la base de datos Cassandra, el protocolo para conectar con ella y que nos generará el módulo para poder trabajar desde PHP, y PHPCassa que será la abstracción de la base de datos donde tenemos los métodos básicos para trabajar con Cassandra: insertar, actualizar, borrar, crear, etc.

 

PREPARANDO EL SISTEMA

Antes de empezar a instalar debemos actualizar el sistema operativos de la forma habitual:

apt-get update
apt-get upgrade

Una vez actualizado el sistema empezamos a instalar.

 

INSTALANDO CASSANDRA

Lo primero que necesitamos hacer para instalar Cassandra es editar los repositorios de Debian:

  1. nano /etc/apt/sources.list

 

Una vez que se abra el editor añadimos las siguientes lineas:

deb http://www.apache.org/dist/cassandra/debian/ 08x main
deb-src http://www.apache.org/dist/cassandra/debian/ 08x main

Como podrás observar después de la ruta del repositorio se ha añadido “08x” estoy indica el número de versión a obtener, en este caso es la versión actual de cassandra al crear este post. No se indica el número de parche, es decir, actualmente se puede descargar Cassandra 8.4, el “.4″ lo obviamos a la hora de los repositorios.

Si dentro de unos meses sale la versión “9.0″ solo tendrás que cambiar el ocho por el nueve.
Volvemos a consola y actualizamos los repositorios.

apt-get update

Nos dará un error en las claves gpg. Procedemos a actualizarlas con las siguientes instrucciones:

  1. gpg --keyserver pgp.mit.edu --recv-keys F758CE318D77295D
  2. gpg --export --armor F758CE318D77295D | sudo apt-key add -

Ojo con el guión del final, hay que añadirlo sino dará error.

Con el paquete 0.7.5 nos da otro error de clave gpg así que también instalamos esta de la misma manera:

gpg --keyserver pgp.mit.edu --recv-keys 2B5C1B00
gpg --export --armor 2B5C1B00 | sudo apt-key add -

Verificamos que tenemos el sistema actualizado.

Actualizamos todos los paquetes que aparezcan.

Procedemos a instalar el paquete de la base de datos NoSQL Cassandra:

  1. apt-get install cassandra

Cassandra necesita a Java para funcionar para ello, una vez instalado Cassandra instalaremos el paquete sun-java6-jdk de la siguiente manera:

  1. apt-get install sun-java6-jdk

En el caso de que no encuentre el paquete verificar que los repositorios de Debian son correctos. Verifica la versión de Java con:

Debería aparecer algo así:

java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)

Se recomienda usar la versión de Java de Sun (Sun JDK) en vez de Open JDK debido a un bug encontrado en el mismo.

Si os muestra algo distinto a esto, escribid el siguiente comando:

update-alternatives --config javac

Os mostrará un listado con los diferentes paquetes instalados en el sistema que pueden ser utilizados para trabajar con Java. Nosotros usaremos el paquete de Sun, así que pulsa el número del paquete para que Debian lo utilice.

Por último, ejecutamos el siguiente comando para construir las dependencias:

dpkg-buildpackage -uc -us

Una vez instalado procedemos a realizar la configuración de Cassandra:

Creamos varias carpetas necesarias si no han sido creadas automáticamente:

  1. mkdir -p {callouts,commitlog,data,saved,caches,staging}
  2. mkdir /var/log/cassandra

Damos permisos a esta carpeta:

chmod -R 777 /var/log/cassandra/

Creamos el archivo /var/log/cassandra/system.log y le damos permisos:

chmod -R 777 /var/log/cassandra/system.log

 

INSTALANDO THRIFT Y LA EXTENSIÓN PARA PHP

Thrift es tan solo el protocolo de conexión para poder utilizar Cassandra. Aunque en la extensión para PHP existen métodos para poder trabajar con cassandra, requieren bastante código por eso utilizaremos PHPCassa como abstracción de la base de datos.

Primero descargamos Thrift desde su web: http://thrift.apache.org/download/ y descomprimimos

  1. tar -xzvf thrift-0.7.0.tar.gz

Nos colocamos dentro de la carpeta de Thrift.

Antes de hacer nada ahí instalamos algunos paquetes que nos serán necesarios:

  1. apt-get install libboost-dev automake libtool flex bison pkg-config g++

Una vez instalados esos paquetes configuramos y construimos Thrift:

  1. ./configure
  2. make

Construimos la interfaz de PHP Thrift para Cassandra:

  1. ./compiler/cpp/thrift -gen php ../ruta-a-cassandra/interface/cassandra.thrift

Copiamos archivos necesario para que PHPCassa funcione:

  1. mkdir -p /usr/share/php/Thrift
  2. cp -R gen-php/ /usr/share/php/Thrift/packages/
  3. cp -R lib/php/src/* /usr/share/php/Thrift/

Cambiamos al directorio del protocolo de Thrif: ruta-a-thrift/lib/php/src/ext/thrift_protocol.

Instalamos el paquete para construir las extensiones de PHP:

  1. apt-get install php5-dev

Construimos la extensión:

  1. phpize
  2. ./configure --enable-thrift_protocol
  3. make

Copiamos la extensión a la siguiente carpeta (cuidado: dependiendo del sistema el nombre de la carpeta de destino puede variar):

  1. cp modules/thrift_protocol.so /usr/lib/php5/20060613/

Habilitamos el módulo creando el archivo /etc/php5/conf.d/thrift_protocol.ini con el siguiente texto:

  1. extension=thrift_protocol.so

Comprobamos la instalación:

  1. php -i | grep -v "PWD" | grep "thrift_protocol"

Si todo ha ido bien, reiniciamos Apache:

  1. /etc/init.d/apache2 restart

Iniciamos Cassandra:

  1. /opt/cassandra/bin/cassandra -f

Y probamos la consola para comprobar que todo ha ido correctamente:

  1. /opt/cassandra/bin/cassandra-cli -host localhost -port 9160

Debería indicarte algo así:

  1. Connected to: "Test Cluster" on localhost/9160
  2. Welcome to cassandra CLI.

 

INSTALANDO PHPCassa

Bajamos PHPCassa desde github: https://github.com/thobbs/phpcassa

Al descomprimir verás cuatro archivos PHP, copia esos archivos a una carpeta del proyecto en el que estés trabajando.

Abre el archivo “connection.php”, la primera línea será una variable global: $GLOBALS['THRIFT_ROOT'], modifica su valor con la ruta hacia los archivos Thrift que copiamos con anterioridad. En mi caso se quedaría así:

  1. <?php
  2. $GLOBALS['THRIFT_ROOT'] = '/usr/share/php/Thrift/';

Con esto finalizamos la instalación de Cassandra para que pueda ser utilizada por PHP.

Os dejo algunas páginas de interés:
CASSANDRA
http://cassandra.apache.org/
http://cassandra.apache.org/download/
http://wiki.apache.org/cassandra/
http://www.apache.org/dist/cassandra/debian/dists/
http://wiki.apache.org/cassandra/DebianPackaging
http://wiki.apache.org/cassandra/CloudConfig
http://cassandra-user-incubator-apache-org.3065146.n2.nabble.com/Cannot-connect-to-Cassandra-td6463518.html
http://sentidoweb.com/2010/03/18/instalar-cassandra-en-ubuntu.php
http://gettingstartedwithcassandra.blogspot.com/2011/06/exception-connecting-to-localhost9160.html
https://wiki.fourkitchens.com/display/PF/Using+Cassandra+with+PHP
http://es.paperblog.com/instalar-cassandra-en-ubuntu-78327/
http://www.unixmen.com/linux-tutorials/960-install-nosql-cassandra-db-in-ubuntu-via-ppa-repository
http://wiki.apache.org/cassandra/ClientOptions

THRIFT
http://thrift.apache.org/

 



PHPCassa
https://github.com/thobbs/phpcassa
http://groups.google.com/group/phpcassa?pli=1

Symfony: La vista (IV), mecanismo de escape

0

Este capítulo del libro me está resultando de lo más pesado, principalmente porque no hay mucho con lo que practicar, ya que la mayoría de la información es teoría basada en donde ubicar cada cosa en cada caso. Aunque las posibilidades que ofrece Symfony a medida que te adentras en él, son enormes.

Para acabar con la vista solo queda ver el mecanismo de escape que utiliza Symfony. Empezemos:

Este apartado del libro comienza así:

Cuando se insertan datos generados dinámicamente en una plantilla, se debe asegurar la integridad de los datos. Por ejemplo, si se utilizan datos obtenidos mediante formularios que pueden rellenar usuarios anónimos, existe un gran riesgo de que los contenidos puedan incluir scripts y otros elementos maliciosos que se encargan de realizar ataques de tipo XSS (cross-site scripting). Por tanto, se debe aplicar un mecanismo de escape a todos los datos mostrados, de forma que ninguna etiqueta HTML pueda ser peligrosa.

ACTIVANDO EL MECANISMO DE ESCAPE

Fácil. El mecanismo de escape se activa en el archivo config/settings.yml de la aplicación utilizando para ello dos parámentros:

  • scaping_strategy: Define la forma en la que las variables están disponibles en la vista.
  • scaping_method: Indica la función que se aplica a los datos.

all:
.settings:
escaping_strategy: both
escaping_method: ESC_ENTITIES

Esto de aquí arriba es lo único que tendrás que escribir para activar el mecanismo de escape. Ahora mismo, nuestra aplicación estaría utilizando el método htmlentities() de PHP para escapar los caracteres de html. Más adelante veremos más valores que pueden tener estos parámentros.

Por ejemplo, si tenemos en nuestra acción esta variable:

$this->prueba = ‘<script>alert(document.cookie)</script>’;

Al tener el mecanismo de escape activado, al mostrarla en la plantilla nos dará el siguiente resultado:

echo $prueba;
=> &gt;&lt;script&gt;alert(document.cookie)&lt;/script&gt;

Si se activa el mecanismo de escape, desde cualquier plantilla se puede acceder a una nueva variable llamada $sf_data. Se trata de un objeto contenedor que hace referencia a todas las variables que se han modificado mediante el sistema de escape. De esta forma, también es posible mostrar el contenido de la variable prueba de la siguiente manera:

echo $sf_data->get(‘prueba’);
=> &gt;&lt;script&gt;alert(document.cookie)&lt;/script&gt;

Con esta clase también podemos acceder a los datos de la variable en crudo, es decir, antes de que sus caracteres fuesen escapados:

echo $sf_data->getRaw(‘prueba’);
=> <script>alert(document.cookie)</script>

OPCIONES PARA scaping_strategy

  • backward compatible mode (o modo retrocompatible): el contenido de las variables no se modifica, pero el contenedor $sf_data almacena una versión modificada de cada variable. De esta forma, los datos de las variables se obtienen en crudo, a menos que se obtenga la versión modificada del objeto $sf_data. Se trata del valor por defecto de la opción, aunque se trata del modo que permite los ataques de tipo XSS.
  • both: a todas las variables se les aplica el mecanismo de escape. Los valores también están disponibles en el contenedor $sf_data. Se trata del valor recomendado, ya que solamente se está expuesto al riesgo si se utilizan de forma explícita los datos originales. En ocasiones, se deben utilizar los valores originales, por ejemplo para incluir código HTML de forma que se interprete en el navegador y no se muestre el código HTML. Si una aplicación se encuentra medio desarrollada y se cambia la estrategia del mecanismo de escape a este valor, algunas funcionalidades pueden dejar de funcionar como se espera. Lo mejor es seleccionar esta opción desde el principio.
  • on: los valores solamente están disponibles en el contenedor $sf_data. Se trata del método más seguro y más rapido de manejar el mecanismo de escape, ya que cada vez que se quiere mostrar el contenido de una variable, se debe elegir el método get() para los datos modificados o el método getRaw() para el contenido original. De esta forma, siempre se recuerda la posibilidad de que los datos de la variable sean corruptos.
  • off: deshabilita el mecanismo de escape. Las plantillas no pueden hacer uso del contenedor $sf_data. Si nunca se va a necesitar el sistema de escape, es mejor utilizar esta opción y no la opción por defecto bc, ya que la aplicación se ejecuta más rápidamente.

OPCIONES PARA scaping_method

  • ESC_RAW: no modifica el valor original.
  • ESC_ENTITIES: aplica la función htmlentities() de PHP al valor que se le pasa y utiliza la opción ENT_QUOTES para el estilo de las comillas.
  • ESC_JS: modifica un valor que corresponde a una cadena de JavaScript que va a ser utilizada como HTML. Se trata de una opción muy útil para escapar valores cuando se emplea JavaScript para modificar de forma dinámica el contenido HTML de la página.
  • ESC_JS_NO_ENTITIES: modifica un valor que va a ser utilizado en una cadena de JavaScript pero no le añade las entidades HTML correspondientes. Se trata de una opción muy útil para los valores que se van a mostrar en los cuadros de diálogo (por ejemplo para una variable llamada miCadena en la instrucción javascript:alert(miCadena);).

APLICANDO EL MECANISMO DE ESCAPE A ARRAYS Y OBJETOS

// Definición de la clase
class miClase
{
public function pruebaCaracterEspecial($valor = ”)
{
return ‘<’.$valor.’>’;
}
}

// En la acción
$this->array_prueba = array(‘&’, ‘<’, ‘>’);
$this->array_de_arrays = array(array(‘&’));
$this->objeto_prueba = new miClase();

// En la plantilla
<?php foreach($array_prueba as $valor): ?>
<?php echo $valor ?>
<?php endforeach; ?>
=> &amp; &lt; &gt;
<?php echo $array_de_arrays[0][0] ?>
=> &amp;
<?php echo $objeto_prueba->pruebaCaracterEspecial(‘&’) ?>
=> &lt;&amp;&gt;

Los métodos de los objetos a los que se aplica el mecanismo de escape aceptan un parámetro adicional:

<?php echo $objeto_prueba->pruebaCaracterEspecial(‘&’) ?>
=> &lt;&amp;&gt;
// Las siguientes 3 líneas producen el mismo resultado
<?php echo $objeto_prueba->pruebaCaracterEspecial(‘&’, ESC_RAW) ?>
<?php echo $sf_data->getRaw(‘objeto_prueba’)->pruebaCaracterEspecial(‘&’) ?>
<?php echo $sf_data->get(‘objeto_prueba’, ESC_RAW)->pruebaCaracterEspecial(‘&’) ?>
=> <&>

Las variables de Symfony también se modifican al activar el mecanismo de escape. Por tanto, las variables $sf_user, $sf_request, $sf_param y $sf_context siguen funcionando, pero sus métodos devuelven sus datos modificados, a no ser que se utilice la opción ESC_RAW como último argumento de las llamadas a los métodos.

Symfony: La vista (III), configuración de la vista

0

La vista en Symfony está dividida en dos partas:

  • Las plantillas (fragmentos de código): donde se recoge el resultado de la acción.
  • El resto: etiquetas meta, título de la página, archivos js y css, acciones que necesitan un layout personalizado (ventanas emergentes, publi) y las acciones que no necesitan layout alguno como las acciones para ajax.

Para modificar todo lo del segundo punto, que en general, podríamos considerar las cabeceras de la página, Symfony utiliza dos formas: a través del archivo de configuración view.yml o a través del objeto sfResponse para poder modificar las cabeceras de forma dinámica desde las acciones.

Si un mismo parámetro de configuración se establece mediante el objeto sfResponse y mediante el archivo view.yml, tiene preferencia el valor establecido mediante el objeto sfResponse.

EL ARCHIVO view.yml

editSuccess:
metas:
title: Edita tu perfil

editError:
metas:
title: Error en la edición del perfil

all:
stylesheets: [mi_estilo]
metas:
title: Mi sitio web

Esto anterior es la configuración de la vista de un módulo. Por defecto el archivo no existe y tendrías que crearlo y guardarlo dentro de la carpeta del módulo así: mimodulo/config/view.yml. Como puedes ver hay tres apartados:

  • editSuccess: Esta configuración se utilizará cuando la acción edit devuelva una respuesta igual a sfView::SUCCESS (o no devuelve nada, ya que es el valor devuelto por defecto).
  • editError: Esta configuración se utilizará cuando la acción edit devulva una respuesta igual a sfView::ERROR.
  • all: Esta es la configuración por defecto del módulo.

Para que veas la configuración en cascada de una aplicación en Symfony mira esto:

  • En apps/miaplicacion/modules/mimodulo/config/view.yml, las definiciones de cada vista solo se aplican a una vista y además sus valores tienen preferencia sobre las opciones generales del módulo.
  • En apps/miaplicacion/modules/mimodulo/config/view.yml, las definiciones bajo all: se aplican a todas las acciones del módulo y tienen preferencia sobre las definiciones de la aplicación.
  • En apps/miaplicacion/config/view.yml, las definiciones bajo default: se aplican a todos los módulos y todas las acciones de la aplicación.

Supongo que te estarás preguntando dónde se definen las cabeceras de la página, pues bien, estás se defienen en el archivo view.yml de la aplicación.

default:
http_metas:
content-type: text/html
metas:
title: symfony project
robots: index, follow
description: symfony project
keywords: symfony, project
language: en
stylesheets: [main]
javascripts: [ ]

has_layout: on
layout: layout

Más adelante explico las distintas opciones de la configuración de la vista. Antes veamos la segunda forma de configurar la vista.

EL OBJETO sfResponse

Aunque el objeto sfResponse pertenece a la vista, se puede acceder a él a través de la acción mediante el método getResponse. Algunos métodos que se utilizan habitualmente:

class mimoduloActions extends sfActions
{
public function executeIndex()
{
$respuesta = $this->getResponse();

// Cabeceras HTTP
$respuesta->setContentType(‘text/xml’);
$respuesta->setHttpHeader(‘Content-Language’, ‘en’);
$respuesta->setStatusCode(403);
$respuesta->addVaryHttpHeader(‘Accept-Language’);
$respuesta->addCacheControlHttpHeader(‘no-cache’);

// Cookies
$respuesta->setCookie($nombre, $contenido, $expiracion, $ruta, $dominio);

// Atributos Meta y cabecera de la página
$respuesta->addMeta(‘robots’, ‘NONE’);
$respuesta->addMeta(‘keywords’, ‘palabra1 palabra2′);
$respuesta->setTitle(‘Mi Página de Ejemplo’);
$respuesta->addStyleSheet(‘mi_archivo_css’);
$respuesta->addJavaScript(‘mi_archivo_javascript’); } }

Los métodos setter mostrados anteriormente que permiten dar un valor a la propiedad, también disponen de un método getter que devuelven el valor de la propiedad.

OPCIONES DE CONFIGURACIÓN DE LA VISTA

Copypasteo la introducción de esta sección del libro de Symfony:

Puede que hayas observador que existen 2 tipos diferentes de opciones para la configuración de la vista:

  • Las opciones que tienen un único valor (el valor es una cadena de texto en el archivo view.yml y el objeto respuesta utiliza un método set para ellas)
  • Las opciones que tienen múltiples valores (el archivo view.yml utiliza arrays para almacenar los valores y el objeto respuesta utiliza métodos de tipo add)

Hay que tener en cuenta por tanto que la configuración en cascada va sobrescribiendo los valores de las opciones de un solo valor y va añadiendo valores a las opciones que permiten valores múltiples. Este comportamiento se entiende mejor a medida que se avanza en este capítulo.

ETIQUETAS META

Las etiquetas <meta> se pueden definir dentro de las claves http_metas: y metas: en el archivo view.yml, o utilizando los métodos addHttpMeta() y addMeta() del objeto sfResponse dentro de la acción:

http_metas:
cache-control: public
metas:
description: Página sobre economía en Francia
keywords: economía, Francia

$this->getResponse()->addHttpMeta(‘cache-control’, ‘public’);
$this->getResponse()->addMeta(‘description’, ‘Página sobre economía en Francia’);
$this->getResponse()->addMeta(‘keywords’, ‘economía, Francia’);

Para las etiquetas <meta>, se puede añadir al método addHttpMeta() (y también a setHttpHeader()) un tercer parámetro con un valor de false para que añadan el valor indicado al valor que ya existía y así no lo reemplacen.

$this->getResponse()->addHttpMeta(‘accept-language’, ‘en’);
$this->getResponse()->addHttpMeta(‘accept-language’, ‘fr’, false);
echo $this->getResponse()->getHttpHeader(‘accept-language’);
=> ‘en, fr’

Para añadir las etiquetas <meta> en la página que se envía al usuario, se deben utilizar los helpers include_http_metas() e include_metas() dentro de la sección <head>.

EL TÍTULO DE LA PÁGINA

indexSuccess:
metas:
title: Los tres cerditos

$this->getResponse()->setTitle(sprintf(‘Los %d cerditos’, $numero));

El título de la página se puede incluir en el layout a través del método include_metas(), a través de include_title() o ambos, ya que es totalmente válido tener una etiqueta <meta name=”title”> o una etiqueta <title>.

INCLUIR ARCHIVOS

indexSuccess:
stylesheets: [miestilo1, miestilo2]
javascripts: [miscript]

$this->getResponse()->addStylesheet(‘miestilo1′);
$this->getResponse()->addStylesheet(‘miestilo2′);
$this->getResponse()->addJavascript(‘miscript’);

La extensión de los archivos no es necesario ponerla, a no ser que tengan una extensión diferente a la habitual (.css para archivos de estilos, .js para archivos javascript).

La inclusión de los archivos en la cabecera de la página es automática, no se necesita ningún método para añadirlos.

Recuerda que se sigue aplicando la configuración en cascada, por tanto los archivos que añadas a view.yml de la aplicación se mostrarán en todas las páginas de la aplicación.

view.yml de la aplicación:

default:
stylesheets: [principal]

view.yml del módulo:

indexSuccess:
stylesheets: [especial]

all:
stylesheets: [otra]

Si no se quiere incluir un archivo definido en alguno de los niveles de configuración superiores, se puede añadir un signo – delante del nombre del archivo en la configuración de más bajo nivel.

Ejemplo de archivo view.yml en el módulo y que evita incluir algunos de los archivos incluidos desde el nivel de configuración de la aplicación:

indexSuccess:
stylesheets: [-principal, especial]

all:
stylesheets: [otra]

Para eliminar todas las hojas de estilos o todos los archivos de JavaScript, se puede utilizar la siguiente sintaxis:

indexSuccess:
stylesheets: [-*]
javascripts: [-*]

Se puede ser todavía más preciso al incluir los archivos, ya que se puede utilizar un parámetro adicional para indicar la posición en la que se debe incluir el archivo (sólo se puede indicar la posición primera o la última):

# En el archivo view.yml
indexSuccess:
stylesheets: [especial: { position: first }]

// En la acción
$this->getResponse()->addStylesheet(‘especial’, ‘first’);

Para modificar el atributo media de la hoja de estilos incluida, se pueden modificar las opciones por defecto de Symfony:

indexSuccess:
stylesheets: [principal, impresora: { media: print }]

$this->getResponse()->addStylesheet(‘impresora’, ”, array(‘media’ => ‘print’));

Html devuelto por Symfony:

$this->getResponse()->addStylesheet(‘impresora’, ”, array(‘media’ => ‘print’));

CONFIGURACIÓN DEL LAYOUT

Normalmente Symfony, por defecto, utilizará la plantilla guardada en la carpeta /templates de la aplicación llamada layout.php, pero podemos indicarle cualquier otro layout:

indexSuccess:
layout: mi_layout

$this->setLayout(‘mi_layout’);

Si no se necesita ningún layout, se puede eliminar:

indexSuccess:
has_layout: false

$this->setLayout(false);

Symfony: La vista (II), ayudantes

0

Los ayudantes o helpers son funciones PHP que permiten agilizar ciertas tareas repetitivas, devuelven código HTML y se utilizan en las plantillas Por ejemplo:

<?php echo input_tag(‘nick’) ?> => <input type=”text” name=”nick” id=”nick” value=”" />

La función input_tag(nombre, valor) genera el código para crear un campo de texto de un formulario con sus atributos básicos (aunque se pueden añadir otros atributos como tercer parámetro en la función). Algunos helpers disponen de cierta inteligencia:

<?php echo auto_link_text(‘Por favor, visita nuestro sitio web www.ejemplo.com’) ?> => Por favor, visita nuestro sitio web <a href=”http://www.ejemplo.com”>www.ejemplo.com</a>

Los helpers deben ser declarados, ya que al ser funciones y no clases no se cargan directamente. Para declarar un helper se hace uso de la función use_helper(‘nombre_del_helper1′, ‘nombre_del_helper2′):

Esta plantilla utiliza un grupo de helpers específicos <?php use_helper(‘Text’) ?> … <h1>Descripción</h1> <p><?php echo auto_link_text($descripcion) ?></p>

Si se quieren añadir más helpers hay que seperarlos con comas. Los helpers pueden ser cargados automáticamente utilizando el archivo de configuración settings.yml. De los siete helpers existentes en Symfony, cuatro (Helper, Tag, Url y Asset) no se pueden eliminar del archivo de configuración, pero los otros tres (Partial, Cache, Form) sí.

Los siete helpers:

  • Helper: se necesita para incluir otros helpers (de hecho, la función use_helper() también es un helper
  • Tag: helper básico para etiquetas y que utilizan casi todos los helpers
  • Url: helpers para la gestión de enlaces y URL
  • Asset: helpers que añaden elementos a la sección <head> del código HTML y que proporcionan enlaces sencillos a elementos externos (imágenes, archivos JavaScript, hojas de estilo, etc.)
  • Partial: helpers que permiten incluir trozos de plantillas
  • Cache: manipulación de los trozos de código que se han añadido a la cache
  • Form: helpers para los formularios

Los helpers más habituales:

/ Grupo Helper
<?php use_helper(‘NombreHelper’) ?>
<?php use_helper(‘NombreHelper1′, ‘NombreHelper2′, ‘NombreHelper3′) ?>

// Grupo Tag
<?php echo tag(‘input’, array(‘name’ => ‘parametro’, ‘type’ => ‘text’)) ?>
<?php echo tag(‘input’, ‘name=parametro type=text’) ?> // Sintaxis alternativa para las opciones
=> <input name=”parametro” type=”text” />
<?php echo content_tag(‘textarea’, ‘contenido de prueba’, ‘name=parametro’) ?>
=> <textarea name=”parametro”>contenido de prueba</textarea>

// Grupo Url
<?php echo link_to(‘Pínchame’, ‘mimodulo/miaccion’) ?>
=> <a href=”/ruta/a/miaccion”>Pínchame</a> // Depende del sistema de enrutamiento

// Grupo Asset
<?php echo image_tag(‘miimagen’, ‘alt=imagen size=200×100′) ?>
=> <img src=”/images/miimagen.png” alt=”imagen” width=”200″ height=”100″/>
<?php echo javascript_include_tag(‘miscript’) ?>
=> <script language=”JavaScript” type=”text/javascript” src=”/js/miscript.js”></script>
<?php echo stylesheet_tag(‘estilo’) ?>
=> <link href=”/stylesheets/estilo.css” media=”screen” rel=”stylesheet” type=”text/css” />

Por último, existe una manera de acceder a los helpers desde otro punto de la aplicación que no sea una plantilla, mediante la función sfLoader::loadHelpers($helpers).

Symfony: La vista (I), fragmentos de código

0

Debido a que la parte de Symfony que explicaré hoy es bastante densa no podré resumir en un solo post todo el capítulo referente a la Vista, por tanto este será el primero de una serie de post sobre la Vista en Symfony que se explica en el manual de Symfony.

La vista

Como ya he comentado en anteriores post, Symfony sigue el sistema de Modelo-Vista-Controlador (MVC) para que la realización de nuestros proyectos estén mucho mejor estructurados y sean más fáciles de comprender por otros programadores.

Symfony para crear las vistas o implementar el diseño que hemos creado a nuestro proyecto, utiliza plantillas, esto son trozos de código html que se unen para formar la página que ha pedido el usuario.

En Symfony todo el diseño se divide de la siguiente manera:

  • Layout: Es la parte del diseño que se mostrará en todas las páginas (cabeceras, pie, menú, etc).
  • Elementos parciales: Si el fragmento contiene poca lógica.
  • Componentes: Si el fragmento tiene mucha lógica o debe acceder a la base de datos.
  • Slots: Si el fragmento va a sustituir a una parte del layout y se mostrará una parte por defecto.

En el libro lo explican bastante bien como se dividen las plantillas, los fragmentos de código que se pueden utilizar, cómo pasar variables desde la acción a los fragmentos de código, y algún detalle más que viene bien conocer. Os dejo el link a los Fragmentos de código.

Normalmente cuando trabajamos con plantillas en nuestros proyectos PHP, utilizamos la instrucción include() y en Symfony podríamos añadir a nuestro código algo como lo siguiente:

<?php include(sfConfig::get(‘sf_app_template_dir’).’/miFragmento.php’) ?>

Pero esta forma de añadir fragmentos de código no es muy limpia y, además, la caché de Symfony no reconoce la instrucción include() con lo que ese fragmento no podría ser cacheado. Aquí es donde entran en juego los fragmentos de código que he comentado anteriormente.

ELEMENTOS PARCIALES

Observa un periódico digital, su portada concretamente, verás que las noticias estan encajadas como en recuadros imaginarios y que cada noticia sigue un patrón: un titular y un pequeño avance de la noticia. Eso es un elemento parcial. Podemos poner ese elemento parcial en cualquier parte de ese periódico digital, ya que siempre será importante que el usuario pueda acceder a otras noticias con un pequeño avance.

Symfony sigue esta misma lógica para los elementos parciales. Estos, al igual que las plantillas, se ubican en la carpeta “templates/” del proyecto y son accesibles desde el módulo en el que se encuentre el archivo, desde otro módulo o desde la carpeta raíz de las plantillas “templates/“. Los elementos parciales se diferencian de las plantillas por llevar un guión bajo al principio del nombre del archivo ( _elementoparcial.php). Veamos como llamar a los elementos parciales desde distintas ubicaciones:

// Incluir el elemento parcial de miaplicacion/modules/mimodulo/templates/_miparcial1.php
// Como la plantilla y el elemento parcial están en el mismo módulo,
// se puede omitir el nombre del módulo
<?php include_partial(‘miparcial1′) ?>

// Incluir el elemento parcial de miaplicacion/modules/otromodulo/templates/_miparcial2.php
// En este caso es obligatorio indicar el nombre del módulo
<?php include_partial(‘otromodulo/miparcial2′) ?>

// Incluir el elemento parcial de miaplicacion/templates/_miparcial3.php
// Se considera que es parte del módulo ‘global’
<?php include_partial(‘global/miparcial3′) ?>

PASANDO VARIABLES AL ELEMENTO PARCIAL

Primero definimos la variable en la acción del módulo llamado mimodulo (mimodulo/actions/actions.class.php)

class mimoduloActions extends sfActions
{
public function executeIndex()
{
$this->total = 100;
}
}

En la plantilla llamamos al elemento parcial con la función include_partial() y le pasamos la variable en mimodulo/templates/indexSuccess.php.

<p>¡Hola Mundo!</p>
<?php include_partial(‘miparcial’, array(‘mitotal’ => $total)
) ?>

De esta manera podremos usar la variable en el elemento parcial en mimodulo/templates/_miparcial.php.

<p>Total: <?php echo $mitotal ?></p>

COMPONENTES

Los componentes son como los módulos, pero más rápidos. Siguen la misma lógica que los módulos y tienen una estructura de archivos parecida. Para nombrar un componente se utiliza la palabra execute seguido del nombre del componente, por ejemplo:

La clase de los componentes, en modules/news/actions/components.class.php

<?php

class newsComponents extends sfComponents
{
public function executeHeadlines()
{
$c = new Criteria();
$c->addDescendingOrderByColumn(NewsPeer::PUBLISHED_AT);
$c->setLimit(5);
$this->news = NewsPeer::doSelect($c);
}
}

La parte visual de los componentes se crea utilizando los elementos parciales. Para nombrarlos se usa lo mismo que para los componentes solo que sustituyendo la palabra execute por un guión bajo.

El elemento parcial, en modules/news/templates/_headlines.php

<div>
<h1>Últimas noticias</h1>
<ul>
<?php foreach($news as $headline): ?>
<li>
<?php echo $headline->getPublishedAt() ?>
<?php echo link_to($headline->getTitle(),’news/show?id=’.$headline->getId()) ?>
</li>
<?php endforeach ?>
</ul>
</div>

Cada vez que se quiera añadir el componente a una plantilla, sólo será necesario escribir el siguiente código:

<?php include_component(‘news’, ‘headlines’) ?>

Paso de parámetros a un componente y su plantilla:

// Llamada al componente
<?php include_component(‘news’, ‘headlines’, array(‘parametro’ => ‘valor’)) ?>

// Dentro del componente
echo $this->parametro;
=> ‘valor’

// Dentro del elemento parcial _headlines.php
echo $parametro;
=> ‘valor’

SLOTS

Aquí debería hablaros de los slots que simplemente son una especie de elemento parcial configurable, y para explicároslo solo se me ocurre hacer un copy&paste del libro, así que os dejo el link (al final de la página) y espero que os ayude.

Optimización de WordPress

Consumo de memoria en distintas versiones de WordPress

2

Como comenté hace unos días realicé varias pruebas para averiguar cuanta memoria consumía WordPress en versiones posteriores a la actual. Aquí os dejo los datos para que podais compararlos con el consumo de vuestro WordPress.

  • Versión 2.2: 5488.4 KB
  • Versión 2.3: 6287.9 KB
  • Versión 2.5: 7164.6 KB
  • Versión 2.6: 9161.2 KB
  • Versión 2.7: 10442.1 KB
  • Versión 2.9: 14215.9 KB
  • Versión 3.0: 15666.1 KB

Las pruebas se han realizado con AppServ 2.5.10 (PHP 5.2.6, Apache 2.2.8, MySQL 5.0.51b) bajo Windows.

Optimización de WordPress

Instalar Eaccelerator y Zend Optimizer en Plesk y CentOS

25

Fin de semana entretenido además de atareado. Y por fin puedo decir que he conseguido instalar Eaccelerator y Zend Optimizer en el VPS.

Después de asegurarme de que todo ha funcionado correctamente, os escribo este post con la pequeña odisea.

Instalar yum

En el último post que escribí os conté que no fui capaz de instalar nada debido a que el comando yum no estaba disponible en el VPS. Bien pues vamos al tema:

Para los que no lo sepais, el comando yum es el “clon” del comando apt-get de las distribuciones basadas en Debian; yum es el comando para las distribuciones RedHat, y CentOS es una de estas. Ambos comandos sirven para instalar, desinstalar, actualizar (tanto programas como la misma distribución), etc.

Para poder usar el comando yum es necesario instalar un paquete para Plesk. Los comandos necesarios son los siguientes:

wget -q -O – http://www.atomicorp.com/installers/atomic |sh

Una vez instalado ya podremos usar el comando yum perfectamente. Así que… ¡Hala! A actualizar el servidor:

yum upgrade

PHP

Para poder instalar Eaccelerator es necesario disponer de PHP 5.x, comprueba tu versión a través del siguiente comando:

php -v

Podeis probar a actualizar la versión de vuestro PHP si veis que no es la actual:

yum update php

Instalar Eaccelerator

Para poder instalar Eaccelerator necesitas varios paquetes que deben estar instalados en tu servidor:

PHP 5, autoconf, automake, libtool y m4

Una vez comprobado que tienes estos paquetes instalados procede a descargar Eaccelerator:

wget http://bart.eaccelerator.net/source/0.9.6.1/eaccelerator-0.9.6.1.zip

Descomprimimos:

unzip eaccelerator-0.9.6.1.zip

Accedemos a la carpeta que se ha creado:

cd eaccelerator-0.9.6.1

Y ejecutamos los siguientes comandos:

phpize
./configure
make
make install

Con estos comandos Eaccelerator se instalará y solo nos quedaría reiniciar Apache:

/etc/init.d/httpd restart

O bien:

service httpd restart

Una vez reiniciado Apache debería mostrarnos, en la versión de php, que Eaccelerator está instalado:

php -v

nos debería mostrar algo como esto:

PHP 5.2.13 (cli) (built: Jun 2 2010 16:29:01)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies
with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by eAccelerator
with Zend Optimizer v3.3.9, Copyright (c) 1998-2009, by Zend Technologies

Zend Optimizer

Con Eaccelerator se consigue que el consumo de memoria se reduzca considerablemente, pero aun se puede reducir más. Para ello instalaremos Zend Optimizer en nuestro servidor.

Esta aplicación es mucho más fácil de instalar que la anterior:

cd /usr/local/src
wget http://www.eth0.us/files/ZendOptimizer-3.3.9-linux-glibc23-x86_64.tar.gz
tar -zxf ZendOptimizer-3.3.9-linux-glibc23-x86_64.tar.gz
cd ZendOptimizer-3.3.9-linux-glibc23-x86_64
./install

Ya está. Reinicia Apache como he indicado anteriormente y comprueba, en la versión de php, que Zend Optimizer está instalado correctamente.

WordPress

Para los que hayais llegado hasta este post buscando como optimizar WordPress, os diré que con estas dos aplicaciones se puede reducir el consumo de memoría a una cuarta parte de lo habitual. Así se ha quedado mi WordPress después de instalar Eaccelerator y Zend Optimizer:

Consumo de memoría después de instalar Eaccelerator y Zend Optimizer

WordPress pasó de consumir 41,79 MB a 11,7 MB (72% de reducción).

Optimización de WordPress

Mi última pesadilla: Optimizar el VPS para WordPress

13

Pesadilla… de tres semanas y pico. Anoche soñé con la lista de procesos del comando top de Linux. Apache consumía cada vez más y más memoría. Por consumir, consumió el Kernel de Linux y se transformó en el Kernel de Windows. Y no se porqué antes de despertarme entre sudores fríos apareció Bill Gates descojonandose a moco tendido. Dios, ¡Qué imagen!, no se me quita de la cabeza.

Durante este tiempo me he didicado a “intentar” optimizar tanto el VPS como WordPress para reducir el consumo de memoría. Aunque he hecho algunas mejoras (pocas por desgracia) sigue cayendose Apache; pero comenzaré por el prinicpio:

¿Porqué un VPS?

  1. Por el precio: Ví un VPS más o menos al mismo precio que un hosting y apliqué el dicho “burro grande ande o no ande”.
  2. Por aprendizaje: Nunca había probado un VPS y quería saber como poder administrarlo, que se puede hacer con él. No jodes tantas cosas como con un dedicado y hasta cierto punto tienes menos responsabilidad y es mucho más barato. Y es el paso lógico antes de administrar un dedicado, en el que ahí estas solo completamente.
  3. Por unificar mis proyectos web: Dispongo de cinco dominios. Para cada uno tengo planes para crear una web con ellos,o en algunos casos ya está creada y online, en otro, estoy esperando a ver que pasa con el VPS y otros solo estan proyectados. Disponer de todas las webs en un solo servidor, ya que no tienen muchas visitas, es muy pero que muy cómodo, además de económico.
  4. Por ahorar costes: Cinco dominios, cinco hostings. Aunque los hay muy baratos (desde un euro) siempre te limitan alguna cosa y no me convencian.
  5. Por libertad: La posibilidad de hacer y deshacer a mi antojo, en definitiva, de tener el control de la máquina (virtual) es una gozada.

Características del VPS

  • Memoría RAM: 256 MB
  • Espacio en disco: 5 GB
  • Transferencia mensual: 150 GB
  • Sistema operativo: CentOS 5
  • Panel de control: Plesk
  • Y obviamente el resto de características habituales: Perl, PHP, MySQL, etc, etc, etc.

El principio

Cuando contraté este VPS, era un puto ignorante, así de claro, desconocía muchas cosas sobre la administración de servidores, su optimización, y sobre todo, las características que había que observar detenidamente antes de contratar nada (en VPS. En hosting, tengo bastante idea). Menos mal que era el más barato xD.

Desde el tercer o cuarto día comenzó a fallar Apache. Los datos que obtenía tanto de Plesk como de Virtuozzo me indicaban que la memoría se saturaba y paraba los servicios. Claro, como un ignorante creé un ticket al proovedor. La respuesta fué rápida (y ahora la más lógica), “actualice su VPS a uno superior”. No comprendía como me podían decir eso. ¡Que sólo es un blog! ¡Que el día que llega a 100 visitas monto la fiesta padre! !Coño, que no es Digg, ni el Mundo! ¿Cómo podía ser que con solo al acceder a la página principal de la administración (el escritorio de WordPress), Apache ya se viniese abajo? ¿Cómo era posible?.

Sólo había una idea en mi cabeza: “Estos del hosting quieren sacarme más pasta” (Viendolo ahora, en cierto sentido, tenía razón). Pero esa idea no soluciona el problema, aunque mi cabezonería la convirtió en  mantra y como con levantar Apache o reiniciar el contenedor volvía todo a funcionar, se quedo así durante meses.

Primeros intentos

No soy una persona que se rinda fácilmente. Yo siempre digo que en informática no hay nada imposible, sino poco presupuesto. Así que comencé a informarme sobre VPS, WordPress, Apache, etc. De esto puede dar fe mi navegador (uso Opera) que ahora mismo tengo abiertas unas 50 pestañas.

Lo primero fue buscar una forma para averiguar cuánta memoría consumía WordPress. Encontré el siguiente código:

$memoria_usada = round(memory_get_usage(1) / 1024,1);
echo ‘Memoria usada: ‘ . round(memory_get_usage() / 1024,1) . ‘ KB de ‘ . $memoria_usada . ‘ KB’;

Este código indica la memoría que había antes de ejcutar el script (que se guarda en la variable $memoria_usada y se pone al inicio del archivo) y la memoría consumida después de ejecutar el script (que se pone al final). Los datos en local que saqué fueron los siguientes:

9 plugins: Memoria usada: 27462 KB de 67.1 KB
Sin plugins: Memoria usada: 20468.8 KB de 67.2 KB
Actualizando el theme: Memoria usada: 21049.1 KB de 67.1 KB (Utilizando el theme que tengo en el blog actualmente, sustituyendo al theme por defecto)

Siento no tener los datos del VPS, pero no varían mucho. Ahora mismo consume 29,5 MB con ocho plugins activos (no son los mismos plugins han variado desde entonces) más el theme.

Las pruebas las realicé con WordPress 3.0.1 con la base de datos tal cual se instala, bajo Windows con la suit de AppServ sin modificaciones.

Yo, cuando ví las cifras, me quedé alucinado: ¡Wordpress consume casi 20,5 MB!. Realicé pruebas con otras versiones de WordPress para verificar que esto era así, es decir, comprobar que con el paso de las versiones el consumo de memoria había aumentado. Que no era cosa mía, sino que es así de chupón. Aunque aquí puede variar el consumo de memoría dependiendo de las reglas de mod_rewrite de Apache, de como esté optimizado PHP y MySQL, etc. El único culpable no es WordPress, pero acojona.

Viendo lo visto, era hora de actuar.

WordPress a dieta

Sabía que existian varios plugins que permitian cachear las páginas del blog y reducir el consumo de memoria y procesador, pero simpre lo había visto en blogs con miles de visitas, no en uno cutre con theme gratuito que no llega a las cien visitas diarias (triste pero cierto).

El primero en activar en el blog, wp-cache, me costó un poco instalarlo, más por mi inexperiencia con cachés que otra cosa (mira que es sencillito el plugin). Al final no se lo que me paso, no lo recuerdo, que lo desactivé. Busqué otro.

WP Super Cache, no mienten los que hablan bien de él, funciona estupendamente, es un poco más complicado de configurar que wp-cache pero el resultado es magnífico. Pero el blog seguía consumiendo casi 30 MB de memoría y Apache se caía. Mejoró la estabilidad del blog un poco, al menos de cara al visitante sí. Pero seguía con el mismo problema: en cuanto entraba en el Escritorio Apache se escoñaba.

Antes de esto probé cada uno de los plugins para ver cual era el que hacía que Apache se cayera nada más entrar en las administración del blog. WordPress.com Stats era el culpable, la establidiad mejoró sustancialmente teniendo este plugin desactivado. Durante unos días pensé que estaba solucionado el problema, nada más lejos de la realidad. Aunque el blog consumia menos memoría, en cuanto hacía algo que requiriese más esfuerzo por parte de la RAM, Apache se venía abajo. Simplemente con entrar varias veces en el escritorio del blog o activar un plugin, Apache caía. Fue frustrante.

Un plugin del que no conocía su existencia es DB Cache Reloaded. Como su nombre indica, permite cachear las consultas a la base de datos, evitando que se conecte a la base de datos cada vez que haya una petición a esta. Reduce el consumo de recursos. Bien. Activado está y funciona de maravilla, aunque de momento no termina de cachear todas las consultas. Tendré que mirar porqué.

Pero el problema continuaba, Apache se caía. Había que entrar en el servidor.

SSH

Tengo que admitir que no me había conectado nunca a otro ordenador a través de SSH, si a través de VNC y VPNs.

Trabajo con Windows XP SP3 principalmente, pero no le hago ascos a las distribuciones linux, todo lo contrarío: en VirtualBox tengo instalados Debian, CentOS, Ubuntu y ChromeOS, y excepto para el tema de configurar la tarjeta gráfica que aun no he conseguido (creo que VirtualBox es el que no la reconoce y por algún motivo envía al SO una tarjeta gráfica compatible con la que tengo, pero me obliga a estar con una resolución de 800×600).

Bien, ¿porqué cuento esto?. Además de por que quería contarselo a alguien xD, por que así comprenderás que después de varios intentos por conectarme al servidor con varios programitas para Windows, arrancase una máquina virtual para conectarme por la consola de linux. ¡Bendita seas!. Hasta que descubrí que lo que me fallaba era el puerto para poder acceder. ¡La ignorancia da la felicidad!.

Una vez conectado al servidor lo primero que hice fue un top de la máquina para conocer el consumo de RAM (la leche no) en tiempo real.

Me indicaba que tenía 512 MB de RAM total y la memoría consumida oscilaba entre los 170 y los 220 MB, aunque en algunos podía llegar a 270 MB. El problema radica en que el VPS no tiene 512 MB de RAM sino 256 MB; los otros 256 es memoría compartida, con lo que no puedo contar con ella para realizar el cálculo.

También hice un free -m para comprobar la memoria, pero top me ofrece más datos.

Observé que cuando se pide al servidor una página apache ejecuta cuatro procesos de sí mismo llegando en varios casos a consumir un 12 por ciento de memoría RAM. Lo normales un 10 por ciento.

A por Apache

Optimizar Apache. Me costó un huevo y medio encontrar la ubicación de los archivos de configuración, pero cuando me enpeño… (/etc/httpd/conf en CentOS). Bien, leí que si realizaba ciertas modificaciónes en el archivo httpd.conf de Apache podría reducir el consumo de memoría. Por defecto la configuración de Apache era la siguiente:

<IfModule prefork.c>
StartServers                     8
MinSpareServers              5
MaxSpareServers            20
ServerLimit                   256
MaxClients                   256
MaxRequestsPerChild   4000
</IfModule>

Se quedo así:

<IfModule prefork.c>
StartServers                      5
MinSpareServers               5
MaxSpareServers             10
ServerLimit                     30
MaxClients                     30
MaxRequestsPerChild 40000
</IfModule>

No solucionó mucho, o por lo menos yo no lo noté. Reduje también varios parámetros más, como el tiempo que espera Apache para cerrar una conexión permanente, etc.

Esto seguía sin mejorar. Probemos con la base de datos

MySQL

Poca optimización realicé aquí, la verdad. Me limite a añadir la configuración para habilitar la caché de la BD, pero no ha hecho mucho. También puede deberse a que el plugin de WordPress que cachea las consultas ya lo está haciendo. No sé. La configuración quedo del siguiente modo:

query_cache_type = 1
query_cache_limit = 1M
query_cache_size = 8M

PHP

Para optimizar PHP necesitaba instalar en el VPS Eaccelerator y el Zend Optimizer, mis pocos intentos me han llevado a pensar que no puedo instalar nada que no sea a través de Plesk o que necesite el comando yum. Por tanto, a día de hoy, PHP está sin optimizar, habrá que enviar un ticket a ver si ellos me lo isntalan…

VPS

CentOS consume memoría, como todos los SO, las veces que he podido ver el consumo de memoría sin Apache, está rondaba entre 60 y 80 MB. Pero no sólo es el sistema operativo el que consume RAM, Plesk también consume lo suyo (unos 50 MB), he deshabilitado el antivirus que me consumía 70 MB cada vez que se iniciaba. Pero aunque el VPS se ha estabilizado hay momentos en los que Apache tiene cuatro procesos abiertos de 50-60 MB cada uno (según el comando top). Excesivo.

Intenté crear un archivo SWAP pero el comando swapon no lo tengo permitido, al menos por SSH.

CONCLUSIONES

  • Sigo valorando distintas opciones respecto a la optimización del VPS, ahora mismo mi mejor baza es Eaccelerator y que me lo instalen en el VPS para reducir la memoría.
  • Seguiré probando con algunnos plugin de WordPress a ver que tal.
  • Si estas interesado en la contratación de un VPS andate con ojo con la RAM.
  • Me he planteado incluso cambiar de VPS o ampliarlo con la misma empresa o marcharme a otra, ya se verá en septiembre.
  • Lo mejor de todo esto: lo aprendido por el camino. No solo conozco un poco mejor los sistemas Linux, sino también Apache, PHP, MySQL y Plesk, y su administración.
  • Bueno, ¿Y vosotros?¿Qué experiencia habeis tenido con los VPS?¿Qué consejos podeis darme? o simplemente ¿Qué opinais? Los comentarios son vuestros… mientras Apache lo permita xD.

LINKS

Os dejo unos links y así libero al navegador de carga, pobre.

Optimización del VPS

Optimización de WordPress

Optimización de PHP

Optimización de Apache

    Instalar PEAR desde WAMP + Bonus track: instalar Symfony desde PEAR

    0

    Hace tiempo que quería crear un post explicando con instalar PEAR en wamp, y además, desde hace unos meses, crear otro explicación como instalar Symfony desde PEAR. y hoy navegando un poco por la red, he encontrado dos fabulosos tutoriales que explica a la perfección estos dos temas. Así que, sin más preambulos, os dejo los links a estos dos geniales post:

    - Instalando PEAR en windows

    - Instalando symfony en windows

    Ir arriba