JeuWeb - Crée ton jeu par navigateur
Optimiser une application Web - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Optimiser une application Web (/showthread.php?tid=4313)

Pages : 1 2 3


Optimiser une application Web - Sephi-Chan - 28-08-2009

Bonsoir,

Suite à la demande et aux discussions qui vont dans ce sens, j'ouvre un débat sur l'optimisation d'une application Web.
  • Comment vous construisez et gérez vos caches (caches de données, caches de vues, etc.) ?
  • Comment vous stockez ces derniers (fichiers, RAM, Memcache, etc.) ?
  • Comment utilisez-vous des caches d'Opcode (APC, eAccelerator, XCache, etc.) ?

Bref, expliquez-nous comment vous vous y prenez pour accélérer votre application Web ! Smile


Sephi-Chan


RE: Optimiser une application Web - Anthor - 29-08-2009

Au niveau du cache OPCode, j'utilise APC, aucune configuration spéciale à appliquer, le tout se fait automatiquement.
Ca s'installe avec pecl : pecl install apc
Et il suffit de rajouter une ligne dans le php.ini : extension = apc.so

Pour les données, APC aussi. Tout est en objet, donc peu de modification à effectuer.

Par exemple, on utilise une classe de cache, là c'est pour l'exemple, sinon j'utilise Zend_Cache :
Code PHP :
<?php
class cache
{
public function
set( $k, $v = null, $ttl = 0 )
{
return
apc_add( $k, $v, $ttl);
}

public function
get( $k )
{
return
apc_fetch( $k );
}

public function
remove( $k )
{
return
apc_delete( $k );
}
}

Ensuite je dispose de classes d'accès aux données.
Code PHP :
<?php
classe models_Users
()
{
protected
$_name = 'users';
protected
$_primary = 'id';

private
$_cache;

public function
init()
{
$this->_cache = new cache();
}

public function
getUserById( $id )
{
$cacheKey = 'models_Users_getUserById_' . $id;

if ( !(
$res = $this->_cache->get($cacheKey)) )
{
// Requete SQL ou autre
$res = $this->find( $id )->current();
$this->_cache->set( $res, $cacheKey );
}

return
$res;
}

public function
removeCache( $id )
{
$cacheKey = 'models_Users_getUserById_' . $id;
$this->_cache->remove($cacheKey)
}
}

Lors de mise à jour, le cache est vidé, et les nouvelles données récupérées en base de données. 98% des requêtes sont ainsi effectués directement en mémoire.

En plus de ça j'utilise le mod_deflate d'Apache pour compresser mes fichiers statiques. et différentes méthodes de cache client.


RE: Optimiser une application Web - Sephi-Chan - 05-09-2009

En ce qui me concerne, j'utilise les divers moyens de cache mis à disposition par Ruby on Rails. Je vais les lister et expliquer rapidement.

Tout d'abord, le page caching, qui consiste simplement à créer physiquement un fichier HTML qui sera rendu quand on appellera un contrôleur (et le code de l'action sera ignoré !).


class UsersController < ApplicationController
caches_page :index

def index
@users = User.all
end

def show
@user = User.find(params[:id])
end
end

Ici, l'action index sera appelée une fois, puis la page rendue sera stockée dans /public/users/index.html et sera rendue à chaque fois qu'on ira sur la page application.com/users/index .

On peut faire expirer le cache grâce à la ligne :


expire_page "/users/index"

Notez qu'on peut également conditionner le cache, ainsi, dans l'exemple qui suit, on ne rend le cache que pour les requêtes qui demandent du XML en rendu :


class UsersController < ApplicationController
caches_page :index, :if => lambda { |controller| controller.request.format.xml? }

# On peut accéder à cette page via application.com/users/index
# ou par application.com/users/index.xml.
def index
@users = User.all

# On indique les formats auxquels on répond.
respond_to do |format|
format.html # On rend la vue /users/index.html.erb
format.xml # On rend rend la vue /users/index.xml.erb
end
end
end


Il existe également le action caching, qui ressemble au page caching à la différence prêt qu'il interroge tout de même le serveur en exécutant les éventuels filtres.


class UsersController < ApplicationController
# On vérifie que l'utilisateur est bien connecté, sinon
before_filter :check_authentication, :except => [ :index ]
caches_action :index

def index
# ...
end

# On accède à la page via application.com/users/1
def show
@user = User.find(params[:id])
end

protected

def check_authentication
# L'implémentation qu'on veut pour vérifier l'authentification.
# Notez qu'en général, on définit cette méthode dans le contrôleur parent
# (ici ApplicationController) afin de pouvoir en hériter dans les autres.
unless session[:user]
flash[:error] = "Vous devez être authentifié."
redirect_to new_user_session_path and return
end
end

end

Ici, on met en cache l'action show, mais on effectue quand même le test d'authentification.
Là encore, on peut conditionner le cas dans lequel on rend le cache.

Notez qu'avec ces caches, le layout (c'est à dire ce qui englobe la vue rendue) est également mis en cache. En passant l'option :layout => false, on peut empêcher ce comportement, c'est d'ailleurs ce que l'on fait si ce layout contient des informations dynamiques, comme le nom de l'utilisateur courant.


J'fais une pause, j'expliquerai les sweepers, memcache, le fragment caching, etc. plus tard (et je foutrais ça dans un article).


Sephi-Chan


RE: Optimiser une application Web - naholyr - 05-09-2009




RE: Optimiser une application Web - QuentinC - 11-09-2009

J'avais à l'origine posté ce message dans un autre topic, je le reposte ici conformément aux recommandations de Séphi-Chan.

J'avais une question à propos d'APC.
Je viens de l'installer et je voulais savoir s'il y avait moyen d'exécuter une certaine action juste avant qu'une variable ne soit supprimée à cause de son TTL. Un genre de destructeur ultime, si on veut bien.


RE: Optimiser une application Web - Anthor - 11-09-2009

Non mais normalement cela ne doit pas poser de problème, puisque tu peux effectuer cette action lorsque le cache est remis en forme.

Tout dépend de ce que tu veux faire.


RE: Optimiser une application Web - QuentinC - 13-09-2009

Citation :Non mais normalement cela ne doit pas poser de problème, puisque tu peux effectuer cette action lorsque le cache est remis en forme.
Tu veux dire quoi par remettre le cache en forme ?

L'idée que j'avais derrière la tête, c'était de balancer l'update SQL à ce moment précis....
Genre j'ai pas eu besoin des données de l'utilisateur X pendant les Y dernières minutes, pouf je l'enregistre. Mais c'est peut-être une mauvaise idée tout compte fait, si vous avez des avis éventuellement là-dessus.


RE: Optimiser une application Web - Sephi-Chan - 13-09-2009

En fait, ça n'apporterai rien par rapport au cycle de vie classique d'un cache, à savoir :
  • La ressource est récupérée dans la source de données ;
  • Puis elle est mise en cache ;
  • Le cache est servi à chaque fois que l'on tente de récupérer cette ressource ;
  • Enfin, elle finit par être modifiée, on la retire alors du cache ;
  • À son prochain appel, la ressource est à nouveau puisé dans la source de données classique puis mise en cache ;

Bien sûr, on peut imaginer une alternative où la ressource est remise en cache après avoir été modifié. Mais ça n'apporte rien non plus.

Le soucis de cette alternative et de celles que tu proposes, c'est qu'au final, ça alourdit le code, alors que le cycle classique est très simple à implémenter et léger en code. Or un code simple est un code facile à maintenir.


Sephi-Chan


RE: Optimiser une application Web - Allwise - 13-09-2009

En parlant d'APC, dans la configuration y a une variable "stats" qui est positionné à 1 par défaut, ce qui fait qu'avant de balancer l'opcode, PHP regarde la date de dernière modification du fichier et regénère le cache au besoin.
A 0 il n'y a pas cette vérification. J'ai pas fait de tests mais je suppose qu'il doit y avoir un gain de perf, ça économise les appels à la fonction stat.


RE: Optimiser une application Web - Sephi-Chan - 13-09-2009

C'est à désactiver une fois en production. Wink


Sephi-Chan

Edit : Effectivement, le désactiver, pas l'activer. Merci Anthor. ^^