rst Apache Mesos构建和安装脚本;可选地在本地运行Master / Slave并对其执行演示(C ++)框架以进行验证

Apache Mesos构建和安装脚本;可选地在本地运行Master / Slave并对其执行演示(C ++)框架,以验证它是否按计划进行

run-mesos.sh
#!/bin/bash
#
# Runs Apache Mesos Master/Slave and (optionally) a demo/test framework
# Created: M. Massenzio, 2015-04-02

source `dirname $0`/common.sh

msg "Running Apache Mesos Master, Slave and Demo Framework (C++)"

if [[ ! -e "./build/bin/mesos-master.sh" ]]; then
    error "Could not find the mesos-master.sh script, are you in the top-level mesos repository?"
    exit 1
fi

cd build

# Creating the logging directory and the work directory
declare -r LOGS="/var/log/mesos"
declare -r WORKDIR="/var/lib/mesos"

for dir in $LOGS $WORKDIR ; do
    if [[ ! -d "$dir" ]]; then
        sudo mkdir -p $dir
        sudo chmod 2775 $dir
        sudo chown $USER:users $dir
    fi
done

# Clean up from previous sessions (will make the slave fail if there was a config change)
rm -f /tmp/mesos/meta/slaves/latest

msg "Starting the Master / Slave, logs in $LOGS, work dir $WORKDIR"
./bin/mesos-master.sh --ip=0.0.0.0 --work_dir=$WORKDIR \
    --log_dir=$LOGS >$LOGS/master.logs 2>&1 &
if [[ $? != 0 ]]; then
    error "Failed starting the Master"
    exit 1
fi
master_pid=$!
echo "$master_pid" >/tmp/MESOS_MASTER_PID

# Cleaning up in case of previous failed runs
rm -rf /tmp/mesos/slaves/

# Note the use of `hostname` here and below, instead of just 'localhost'; this is due to the fact
# that the Master tries to auto-resolve its hostname and (where DNS resolution is not enabled and
# it relies instead on /etc/hosts) this will cause mismatched servername between slave/master/framework
# (This seems particularly bad in Ubuntu, where the hostname is mapped in /etc/hosts to 127.0.1.1)
./bin/mesos-slave.sh --master=`hostname`:5050 > $LOGS/slave.logs 2>&1 &
if [[ $? != 0 ]]; then
    error "Failed starting the Slave"
    exit 1
fi
slave_pid=$!
echo "$slave_pid" >/tmp/MESOS_SLAVE_PID

msg "Master / Slave running in background in this session"
msg "Master PID: $master_pid"
msg "Slave PID: $slave_pid"
msg "To terminate use : kill \`cat /tmp/MESOS_MASTER_PID\` && kill \`cat /tmp/MESOS_SLAVE_PID\`"
echo
msg "Starting the test framework - check progress in the Web UI at http://localhost:5050"
msg "This should complete reasonably quickly, if it just hangs around, probably the slave exited"
msg "Check the slave logs in $LOGS/slave.logs (terminate this script with Ctrl-C)"

# TODO: we could actually start this in background, grab the PID, sleep for a while, then kill it
#       if it hasn't terminated yet (overkill?)
./src/test-framework --master=`hostname`:5050
install-mesos.sh
#!/bin/bash

# Created: M. Massenzio, 2015-04-02

source `dirname $0`/common.sh
declare -r VERSION=${1:-"0.22.0"}

# Get Mesos - update the $VERSION if you need a more recent release
declare -r dir="${HOME}/mesos-dev"
msg "Getting Mesos $VERSION and unpacking to $dir"
mkdir -p $dir
cd $dir

msg "Downloading Apache Mesos ($VERSION)"
wget http://www.apache.org/dist/mesos/$VERSION/mesos-$VERSION.tar.gz
if [[ ! -e "mesos-$VERSION.tar.gz" ]]; then
    error "Failed to download Mesos distribution: mesos-$VERSION.tar.gz"
    exit 1
fi
tar -zxf mesos-$VERSION.tar.gz

# Change working directory (the actual name will depend on Mesos version no.)
cd $dir/mesos-$VERSION

# Running the build script
msg "Running the Build script"
wrap `dirname $0`/build-mesos.sh


read -p "Do you want to run a test framework (y/n)? " choice
if [[ $choice == 'y' ]]; then
    `dirname $0`/run-mesos.sh
fi
common.sh
#!/bin/bash
#
# Common utility functions
# Created: M. Massenzio, 2015-04-02

# Emits a string to console (poor man's log)
# with an optional log level (can be anything, will be prepended to the message)
#
# usage: msg 'msg' [level]
function msg {
    local level=${2:-"INFO"}
    echo "[$level] $1"
}

# Emits an Error message
#
# usage: error "Something went wrong"
function error {
    msg $1 "ERROR"
}

# Wraps a command and exits if it fails
#
# usage: wrap cat /tmp/foo/bar
function wrap {
    local CMD="$@"
    $@
    if [[ $? != 0 ]]; then
        error "Failed: $CMD"
        exit 1
    fi
}
build-mesos.sh
#!/bin/bash
#
# Builds the Apache Mesos distribution
# Created: M. Massenzio, 2015-04-02

source `dirname $0`/common.sh

# Ensure apt-get is up to date.
sudo apt-get update && sudo apt-get -y upgrade

# Install build tools.
msg "Installing necessary dependencies, go grab a book: this WILL take time"
sudo apt-get -y install build-essential python-dev python-boto \
 libcurl4-nss-dev libsasl2-dev \
 maven libapr1-dev libsvn-dev
 

# Install OpenJDK java, only if needed
JAVAC=$(which javac)
if [[ -z $JAVAC ]]; then
    msg "Installing Open JDK 7"
    sudo apt-get install -y openjdk-7-jdk
fi

# Check that we are in the right directory
if [[ ! -e bootstrap ]]; then
    error "This does not appear to be Mesos's top-level directory"
    error "This is the current directory: `pwd`"
    exit 1
fi

# Only needed for building from git cloned repo
if [[ -d .git ]]; then
     # Install autotoconf, automake and libtool
    sudo apt-get install -y autoconf libtool
    msg "Running the bootstrap script"
    wrap ./bootstrap
fi

# Configure and build.
msg "Building Mesos, this will take a long time..."
# TODO: should we run make clean first?
mkdir build
cd build
wrap ../configure
wrap make

# Run test suite.
msg "Testing build"
wrap make check

# Install (***Optional***).
msg "All tests passed; now installing to your system..."
wrap sudo make install

mesos_lib=$(echo $LD_LIBRARY_PATH | grep /usr/local/lib)
if [[ -z $mesos_lib ]]; then
    msg "Adding /usr/local/lib to LD_LIBRARY_PATH to .bashrc"
    echo "export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/local/lib" >> ~/.bashrc
fi 
msg "Mesos install successful" "SUCCESS"
README.rst
==========================
Apache Mesos Build scripts
==========================

The `Getting started`_ instructions are a good start (no surprise there!) but are somewhat incomplete and currently look a bit outdated (I plan to fix them soon): however, the outcome has been that I have struggled more than I felt necessary in building and running Mesos on a dev VM (Ubuntu 14.04 running under VirtualBox).

Some of the issue seem to arise from the unfortunate combination of Mesos Master trying to guess its own IP address, the VM being (obviously) non-DNS resolvable and, eventually, the Slave and the Framework failing to properly communicate with the Master.

In the process of solving this, I ended up automating all the dependencies installation, building and running the framework; I have then broken it down into the following modules to make it easier to run only parts of the process.

Installation
------------

There are two ways of obtaining an Apache Mesos distribution: either via a tarball, or cloning the repo_; either are supported, but will require running the scripts differently: they should all be copied inside the same directory (eg ``/home/user/scripts``) and run from there.

Obviously, make them executable via ``chmod a+x /home/user/scripts/{build,install,run}-mesos.sh``

This has been tested both on a VM and a physical box, both running Ubuntu 14.04.

Running
-------

If you want to download and install from the tarball, execute::

    /path/to/script/install-mesos.sh

optionally followed by the version number (eg, ``0.23.0``): it currently defaults to ``0.22.0``.

If you have already cloned the git repo_, just run::

    /path/to/script/build-mesos.sh

optionally followed by::

    /path/to/script/run-mesos.sh

**NOTE** As these scripts need to ``cd`` in the correct directories, due to the expansion of ``dirname $0``, this will fail unless it's run with an absolute path (as shown above) or using shell expansion wildcards (eg ``~``).  

*Running it like ``./my_scripts/mesos-install.sh`` will most likely fail.*

.. _repo: https://github.com/mesosphere/mesos
.. _Getting started: http://mesos.apache.org/gettingstarted/

rst [Nginx - 在nginx web服务器上安装comodo]使用Nginx安装Comodo PositiveSSL证书的步骤。 #All #Server #Nginx #Script

[Nginx - 在nginx web服务器上安装comodo]使用Nginx安装Comodo PositiveSSL证书的步骤。 #All #Server #Nginx #Script

install-comodo-ssl-cert-for-nginx.rst
Setting up a SSL Cert from Comodo
=================================

I use `Namecheap.com <http://www.namecheap.com/?aff=83780>`_ as a registrar, and they resale
SSL Certs from a number of other companies, including `Comodo <http://www.comodo.com/>`_.

These are the steps I went through to set up an SSL cert.

Purchase the cert
-----------------

Prior to purchasing a cert, you need to generate a private key, and a CSR file
(Certificate Signing Request). You'll be asked for the content of the CSR file
when ordering the certificate.

::

    openssl req -new -newkey rsa:2048 -nodes -keyout example_com.key -out example_com.csr

This gives you two files:

* ``example_com.key`` -- your Private key. You'll need this later to configure ngxinx.
* ``example_com.csr`` -- Your CSR file.

Now, purchase the certificate [1]_, follow the steps on their site, and you should soon get an 
email with your *PositiveSSL Certificate*. It contains a zip file with the following:

* Root CA Certificate - `AddTrustExternalCARoot.crt`
* Intermediate CA Certificate - `COMODORSAAddTrustCA.crt`
* Intermediate CA Certificate - `COMODORSADomainValidationSecureServerCA.crt`
* Your PositiveSSL Certificate - `www_example_com.crt` (or the subdomain you gave them)

Install the Commodo SSL cert
----------------------------

Combine everything for nginx [2]_:

1. Combine the above crt files into a bundle (the order matters, here)::

    cat www_example_com.crt COMODORSADomainValidationSecureServerCA.crt  COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > ssl-bundle.crt

2. Store the bundle wherever nginx expects to find it::

    mkdir -p /etc/nginx/ssl/example_com/
    mv ssl-bundle.crt /etc/nginx/ssl/example_com/

3. Ensure your private key is somewhere nginx can read it, as well.::

    mv example_com.key /etc/nginx/ssl/example_com/

4. Make sure your nginx config points to the right cert file and to the private
   key you generated earlier::

    server {
        listen 443;

        ssl on;
        ssl_certificate /etc/nginx/ssl/example_com/ssl-bundle.crt;
        ssl_certificate_key /etc/nginx/ssl/example_com/example_com.key;

        # side note: only use TLS since SSLv2 and SSLv3 have had recent vulnerabilities
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

        # ...

    }

6. Restart nginx.


.. [1] I purchased mine through Namecheap.com.
.. [2] Based on these instructions: http://goo.gl/4zJc8

rst first_triathlon.rst

first_triathlon.rst
PRZYGOTOWANIE ORGANIZACYJNO-SPRZĘTOWE:

http://www.biecdalej.pl/2014/07/ten-z-poradami-dla-triathlonowych-debiutantow.html

http://runeat.pl/6-rad-jak-nie-schrzanic-tri-startu/

http://2xtri.pl/spakowac-sie-zawody/

PŁYWANIE (open water):

http://akademiatriathlonu.pl/publicystyka/aktualnosci/publicystyka/865-jakich-bledow-unikac-plywajac-na-wodach-otwartych

UNIKNIJ TYCH BŁĘDÓW:

http://niemaniemoge.pl/janusze-trajlonu-laczmy-sie/

W DOBRYM MOMENCIE ZRÓB DOBRY PEŁEN DYSTANS - KILKA MIEJSCÓWEK W EUROPIE:

- Challange Roth (http://www.challenge-roth.com/)

- Ironman Austria (http://eu.ironman.com/triathlon/events/emea/ironman/austria.aspx)

- Ironman Frankfurt (http://eu.ironman.com/triathlon/events/emea/ironman/frankfurt.aspx)

rst 问题报告模板

问题报告模板

issue_report_template.rst
# Reporter #

Your Name and/or Email / Anonymous (add and remove as appropriate)

# Issue Type #

Bug / Feature Request / Suggestion / Feedback (remove as appropriate)

# Platform #

Operating System: (add as appropriate)
Browser: (add as appropriate)
Browser Version: (add as appropriate)

# Severity #

(Remove as appropriate)

Critical: Application crash, Loss of data.
Major: Major loss of function.
Minor: Minor loss of function.
Trivial: Minor enhancements.
Enhancement: Request for new feature or some enhancement in existing one.

# Description #

Add your comments here:


## For bugs ##

### What was supposed to happen? ###

(Add as appropriate)

### What did happen? ###

(Add as appropriate)

### How to reproduce? ###

(Add as appropriate)

rst 在生产中设置django网站的教程。

在生产中设置django网站的教程。

gistfile1.rst
**********************************************************************
Set up Django, Nginx and Gunicorn in a Virtualenv controled by Supervisor
**********************************************************************

Steps with explanations to set up a server using:

* Virtualenv
* Virtualenvwrapper
* Django
* Gunicorn
* Nginx
* Supervisor

Concept
=======

Nginx will face the outside world. It will serve media files (images, CSS, etc) directly from the file system. However, it can't talk directly to Django applications; it needs something that will run the application, feed it requests from the web, and return responses.

That's Gunicorn's job. Gunicorn will create a Unix socket, and serve responses to nginx via the wsgi protocol - the socket passes data in both directions::

    The outside world <-> Nginx <-> The socket <-> Gunicorn

All this family will live into a Virtualenv. Already wondered why Virtualenv is so useful when you develop Pythons's applications? 
Continue to read and you will understand.

Before you start
================

1. Virtualenv
----------

If you don't already use a Virtualenv, you really should consider using it. In a nutshell, the fact is that your operating system have a lot of core modules which depends of Python. That rule is especially right if you use Ubuntu.
So, do you really need to broke up something existant to create somethin new? Well, some guys could answer you "Yes". I'll teach you how to say "No" to them !
Virtualenv will create a dedicated virtual environment with his python binary as well as his own modules. With that method, your Virtualenv will be isolated from the rest of the system. 

1.5 Pip (optional, but higly recommanded)
-------------------------------------

If you use Pip, and I clearly recommand to use it, Virtualenv will simplify your life, because if you play well, you only have to do ::

    pip freeze > requirements.txt

to print a list of all the modules needed by your project into a file. When you will deploy it, you will be able to install all those module with a ::

    pip install -r requirements.txt

2. Virtualenvwrapper
-----------------

What ? I didn't explained how to use Virtualenv? Well, indeed I lied. We won't be using Virtualenv directly. We will use a wrapper. Virtualenvwrapper to be right. Original, isn't it?
Virtualenvwrapper will allow you to easily create virtualenv and switching between them.

Let's get started ! To install virtualenvwrapper, install it with Pip, apt-get, whatever::

    pip install virtualenvwrapper

Virtualenvwrapper is now installed? Let's play with him. First, you will need to modify your .bashrc with your favourite text editor. Add this lines at the and of your .bashrc ::

    export WORKON_HOME=~/.virtualenvs
    export PROJECT_HOME=/path/to/your/project/home
    source /usr/local/bin/virtualenvwrapper.sh

WORKON_HOME is required but PROJECT_HOME is needless. Don't forget to always put ALL the export's directives before sourcing your file.
Seems legit for you?  Here, have my like !

Now, let's activate our .bashrc. If you are a UNIX guru, you have problably already did it before I explained it. If not, here is the command ::

    source .bashrc

If all is good, your stdout will be sourced byt the output of the Virtualenvwrapper creating script. You can verify it by searching a .virtualenvs folder is your home directory.

Now, let's ceate our virtualenv for our project. You can name it whatever your want and even if you don't remember, just go into your .virtualenvs folder and the name of your virtualenv will be one of the folder.
The command for creating one is ::

    mkvirtualenv nameofyourproject

The command for working on a specified virtualenv is ::

    workon nameofyourproject

The command for deactivate a specified virtualenv is ::

    deactivate nameofyourproject

And finally the command to remove a specified virtualenv is ::

    rmvirtualenv nameofyourproject

That's all the command you need to remember. If the workon command has successfully created a virtualenv, your should see the name of your project between parentheses in the left of your username@nameofyourcomputer. Something like that ::

    (nameofyourproject)username@nameofyourcomputer

All is good, Okey, let's move to the next of the story.

! REMEMBER TO DO ALL THE NEXT PART IN YOUR VIRTUALENV. ONLY SUPERVISOR WILL BE INSTALLED OUTSIDE YOUR VIRTUALENV !

1. Django
------

I'm assuming you are using Django 1.4.x. Everything should be fine from our right for Django 1.5. Anayway, if you created your project in 1.4, it should have automatically created a wsgi module. If you're using an earlier version, you will have to find a Django wsgi module for your project. Here is mine modified for exemple ::

    import os
    import sys


    root = os.path.join(os.path.dirname(__file__), '..')
    sys.path.insert(0, root)


    os.environ['DJANGO_SETTINGS_MODULE'] = 'nameofyourproject.settings'


    import django.core.handlers.wsgi
    application = django.core.handlers.wsgi.WSGIHandler()

    # This application object is used by any WSGI server configured to use this
    # file. This includes Django's development server, if the WSGI_APPLICATION
    # setting points here.
    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()

   # Apply WSGI middleware here.
   # from helloworld.wsgi import HelloWorldApplication
   # application = HelloWorldApplication(application)

Note that I'm also assuming a Django 1.4 project structure, in which you see paths like::

	/path/to/your/project/project/

(i.e. it creates nested directories with the name of your project). Adjust the examples if you using an earlier Django.

It will also be helpful if you are in your Django project's directory. If you don't have one ready, just create a directory for now.

About the domain and port
-------------------------

I'll call your domain domain.tld. Substitute your own FQDN or IP address.

Throughout, I'm using the port (:8000) for tests because it is the same port as Django's dev web server. The default port for http (:80) will be used for real deployment. You can use whatever port you want of course, but if you don't know what NAT is, don't do it.

Basic Gunicorn installation and configuration
=========================================

Install Gunicorn
-------------
As we said earlier, Gunicorn will serve the core of our application, just like the Django's development web server would do it. Let's install it ::

    pip install gunicorn

Basic test
----------

Create a file called myapp.py::

    def app(environ, start_response):
        data = "Hello, World!\n"
        start_response("200 OK", [
            ("Content-Type", "text/plain"),
            ("Content-Length", str(len(data)))
        ])
    return iter([data])

Run::

	gunicorn -w 4 myapp:app

This should serve a hello world message directly to the browser on port 8000. Visit::

	http://127.0.0.1:8000

to check.                       

Test your Django project
------------------------

Now we want gunicorn to do the same thing, but to run a Django site instead of the test.py module.

But first, make sure that your project actually works! Now you need to be in your Django project directory.

::

	python manage.py runserver 0.0.0.0:8000

Now run it using gunicorn::

	gunicorn nameofyourapp.wsgi:app

Point your browser at the server; if the site appears, it means gunicorn can serve your Django application from your virtualenv. Media/static files may not be served properly, but don't worry about that.

Now normally we won't have the browser speaking directly to gunicorn: nginx will be the go-between.

Basic nginx
===========

Install nginx
-------------

The version of Nginx from Debian stable and Ubuntu is rather old. We'll install from backports for Debian and PPA for Ubuntu.

Debian::

	sudo nano /etc/apt/sources.list     # edit the sources list

Add::

	# backports
	deb http://backports.debian.org/debian-backports squeeze-backports main

Run::

	sudo apt-get -t squeeze-backports install nginx	# install nginx

For Ubuntu::

	sudo -s
	nginx=stable # use nginx=development for latest development version
	add-apt-repository ppa:nginx/$nginx
	apt-get update 
	apt-get install nginx

For both::

	sudo /etc/init.d/nginx start	# start nginx

And now check that the server is serving by visiting it in a web browser on port 80 - you should get a message from nginx: "Welcome to nginx!"

Configure nginx for your site
-----------------------------

Create a file called nginx.conf, and put this in it::

    server {
        # the port your site will be served on
        listen      80;
        # the domain name it will serve for
        server_name .domain.tld ip.adress;   # substitute by your FQDN and machine's IP address
        charset     utf-8;

        #Max upload size
        client_max_body_size 75M;   # adjust to taste

        # Django media
        location /media  {
    	    alias /var/www/path/to/your/project/media;      # your Django project's media files
        }

        location /assets {
    	    alias /var/www/path/to/your/project/static;     # your Django project's static files
        }

        # Finally, send all non-media requests to the Django server.
        location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

Move your file to /etc/nginx/sites-enabled so nginx can see it::

	sudo mv /path/to/your/project/nginx.conf /etc/nginx/sites-enabled/

Basic nginx test
----------------

Restart nginx::

	sudo /etc/init.d/nginx restart

Check that media files are being served correctly:

Add an image called media.png to the /path/to/your/project/project/media directory

Visit 

http://domain.tld:80/media/media.png     

If this works, you'll know at least that nginx is serving files correctly.

Running the Django application with uswgi and nginx
===================================================

Let's run our Django application::

	gunicorn nameofyourapp.wsgi:app

Now gunicorn and nginx should be serving up your Django application.

Make gunicorn startup when the system boots
========================================

The last step is to make it all happen automatically at system startup time.

To do this, we will install a programm called supervisor::

    sudo pip install supervisor

Sudo in front of your command is important, because it means that our supervisor programm will be installed in the system and not in a virtualenv.

Now, we will create a bash file to execute some commands such as activate our virtualenv and browsing to our directory. So create a nameoryourproject.sh file::

    #!/bin/bash
    WORKING_DIR=/path/to/your/project
    ACTIVATE_PATH=/path/to/your/virtualenv/bin/activate
    cd ${WORKING_DIR}
    source ${ACTIVATE_PATH}
    exec $@

Next, we create a file named supervisord.conf and we put it in /etc/ ::

    ; Sample supervisor config file.
    ;
    ; For more information on the config file, please see:
    ; http://supervisord.org/configuration.html
    ;
    ; Note: shell expansion ("~" or "$HOME") is not supported.  Environment
    ; variables can be expanded using this syntax: "%(ENV_HOME)s".
    
    [unix_http_server]
    file=/tmp/supervisor.sock   ; (the path to the socket file)
    chmod=0700                 ; socket file mode (default 0700)
    chown=root:root       ; socket file uid:gid owner
    ;username=noname              ; (default is no username (open server))
    ;password=noname               ; (default is no password (open server))

    ;[inet_http_server]         ; inet (TCP) server disabled by default
    ;port=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)
    ;username=noname              ; (default is no username (open server))
    ;password=noname               ; (default is no password (open server))

    [supervisord]
    logfile=/var/log/supervisord/supervisord.log ; (main log file;default $CWD/supervisord.log)
    logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
    logfile_backups=10           ; (num of main logfile rotation backups;default 10)
    loglevel=info                ; (log level;default info; others: debug,warn,trace)
    pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
    nodaemon=true               ; (start in foreground if true;default false)
    minfds=1024                  ; (min. avail startup file descriptors;default 1024)
    minprocs=200                 ; (min. avail process descriptors;default 200)
    ;umask=022                   ; (process file creation umask;default 022)
    user=root                 ; (default is current user, required if root)
    ;identifier=supervisor       ; (supervisord identifier, default is 'supervisor')
    ;directory=/tmp              ; (default is not to cd during start)
    ;nocleanup=true              ; (don't clean up tempfiles at start;default false)
    ;childlogdir=/tmp            ; ('AUTO' child log dir, default $TEMP)
    ;environment=KEY=value       ; (key value pairs to add to environment)
    ;strip_ansi=false            ; (strip ansi escape codes in logs; def. false)
    
    ; the below section must remain in the config file for RPC
    ; (supervisorctl/web interface) to work, additional interfaces may be
    ; added by defining them in separate rpcinterface: sections
    [rpcinterface:supervisor]
    supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
    
    [supervisorctl]
    serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket
    ;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
    ;username=www-data              ; should be same as http_username if set
    ;password=www-data                ; should be same as http_password if set
    ;prompt=mysupervisor         ; cmd line prompt (default "supervisor")
    ;history_file=~/.sc_history  ; use readline history if available
    
    ; The below sample program section shows all possible program subsection values,
    ; create one or more 'real' program: sections to be able to control them under
    ; supervisor.
    
    ;[program:theprogramname]
    ;command=/bin/cat              ; the program (relative uses PATH, can take args)
    ;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
    ;numprocs=1                    ; number of processes copies to start (def 1)
    ;directory=/tmp                ; directory to cwd to before exec (def no cwd)
    ;umask=022                     ; umask for process (default None)
    ;priority=999                  ; the relative start priority (default 999)
    ;autostart=true                ; start at supervisord start (default: true)
    ;autorestart=unexpected        ; whether/when to restart (default: unexpected)
    ;startsecs=1                   ; number of secs prog must stay running (def. 1)
    ;startretries=3                ; max # of serial start failures (default 3)
    ;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)
    ;stopsignal=QUIT               ; signal used to kill process (default TERM)
    ;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
    ;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
    ;killasgroup=false             ; SIGKILL the UNIX process group (def false)
    ;user=chrism                   ; setuid to this UNIX account to run the program
    ;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
    ;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
    ;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
    ;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
    ;stdout_events_enabled=false   ; emit events on stdout writes (default false)
    ;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
    ;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)
    ;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
    ;stderr_events_enabled=false   ; emit events on stderr writes (default false)
    ;environment=A=1,B=2           ; process environment additions (def no adds)
    ;serverurl=AUTO                ; override serverurl computation (childutils)
    
    ; The below sample eventlistener section shows all possible
    ; eventlistener subsection values, create one or more 'real'
    ; eventlistener: sections to be able to handle event notifications
    ; sent by supervisor.
    
    ;[eventlistener:theeventlistenername]
    ;command=/bin/eventlistener    ; the program (relative uses PATH, can take args)
    ;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
    ;numprocs=1                    ; number of processes copies to start (def 1)
    ;events=EVENT                  ; event notif. types to subscribe to (req'd)
    ;buffer_size=10                ; event buffer queue size (default 10)
    ;directory=/tmp                ; directory to cwd to before exec (def no cwd)
    ;umask=022                     ; umask for process (default None)
    ;priority=-1                   ; the relative start priority (default -1)
    ;autostart=true                ; start at supervisord start (default: true)
    ;autorestart=unexpected        ; whether/when to restart (default: unexpected)
    ;startsecs=1                   ; number of secs prog must stay running (def. 1)
    ;startretries=3                ; max # of serial start failures (default 3)
    ;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)
    ;stopsignal=QUIT               ; signal used to kill process (default TERM)
    ;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
    ;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
    ;killasgroup=false             ; SIGKILL the UNIX process group (def false)
    ;user=chrism                   ; setuid to this UNIX account to run the program
    ;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
    ;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
    ;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
    ;stdout_events_enabled=false   ; emit events on stdout writes (default false)
    ;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
    ;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stderr_logfile_backups        ; # of stderr logfile backups (default 10)
    ;stderr_events_enabled=false   ; emit events on stderr writes (default false)
    ;environment=A=1,B=2           ; process environment additions
    ;serverurl=AUTO                ; override serverurl computation (childutils)
    
    ; The below sample group section shows all possible group values,
    ; create one or more 'real' group: sections to create "heterogeneous"
    ; process groups.
    
    ;[group:thegroupname]
    ;programs=progname1,progname2  ; each refers to 'x' in [program:x] definitions
    ;priority=999                  ; the relative start priority (default 999)
    
    ; The [include] section can just contain the "files" setting.  This
    ; setting can list multiple files (separated by whitespace or
    ; newlines).  It can also contain wildcards.  The filenames are
    ; interpreted as relative to this file.  Included files *cannot*
    ; include files themselves.
    
    ;[include]
    ;files = relative/directory/*.ini
    [program:nameofyourprogram]
    directory = /path/of/your/project/
    user = www-data
    command = /path/to/your/nameofyourproject.sh gunicorn nameofyourproject.wsgi:application
    stdout_logfile = /var/log/supervisord/access.log
    stderr_logfile = /var/log/supervisord/error.log

After, we will create a file which will ask supervisord to boot at the startup.

Create a file named supervisord::

    # Supervisord auto-start
    #
    # description: Auto-starts supervisord
    # processname: supervisord
    # pidfile: /var/run/supervisord.pid
 
    SUPERVISORD=/usr/local/bin/supervisord
    SUPERVISORD_ARGS='-c /etc/supervisord.conf'
    SUPERVISORCTL=/usr/local/bin/supervisorctl

    case $1 in
    start)
        echo -n "Starting supervisord: "
        $SUPERVISORD $SUPERVISORD_ARGS
        echo
        ;;
    stop)
        echo -n "Stopping supervisord: "
        $SUPERVISORCTL shutdown
        echo
        ;;
    restart)
        echo -n "Stopping supervisord: "
        $SUPERVISORCTL shutdown
        echo
        echo -n "Starting supervisord: "
        $SUPERVISORD $SUPERVISORD_ARGS
        echo
        ;;
    esac

Make it executable ::

    chmod +x supervisord

Move it to /etc/init.d ::

    mv supervisord /etc/init.d/

Make it boot at the start ::

    sudo update-rc.d supervisord defaults

Reboot your system and your website should live through the ages.

rst 使用Nginx安装Comodo PositiveSSL证书的步骤。

使用Nginx安装Comodo PositiveSSL证书的步骤。

install-comodo-ssl-cert-for-nginx.rst
Setting up a SSL Cert from Comodo
=================================

I use `Namecheap.com <http://www.namecheap.com/?aff=83780>`_ as a registrar, and they resale
SSL Certs from a number of other companies, including `Comodo <http://www.comodo.com/>`_.

These are the steps I went through to set up an SSL cert.

Purchase the cert
-----------------

Prior to purchasing a cert, you need to generate a private key, and a CSR file
(Certificate Signing Request). You'll be asked for the content of the CSR file
when ordering the certificate.

::

    openssl req -new -newkey rsa:2048 -nodes -keyout example_com.key -out example_com.csr

This gives you two files:

* ``example_com.key`` -- your Private key. You'll need this later to configure ngxinx.
* ``example_com.csr`` -- Your CSR file.

Now, purchase the certificate [1]_, follow the steps on their site, and you should soon get an 
email with your *PositiveSSL Certificate*. It contains a zip file with the following:

* Root CA Certificate - `AddTrustExternalCARoot.crt`
* Intermediate CA Certificate - `COMODORSAAddTrustCA.crt`
* Intermediate CA Certificate - `COMODORSADomainValidationSecureServerCA.crt`
* Your PositiveSSL Certificate - `www_example_com.crt` (or the subdomain you gave them)

Install the Commodo SSL cert
----------------------------

Combine everything for nginx [2]_:

1. Combine the above crt files into a bundle (the order matters, here)::

    cat www_example_com.crt COMODORSADomainValidationSecureServerCA.crt  COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > ssl-bundle.crt

2. Store the bundle wherever nginx expects to find it::

    mkdir -p /etc/nginx/ssl/example_com/
    mv ssl-bundle.crt /etc/nginx/ssl/example_com/

3. Ensure your private key is somewhere nginx can read it, as well.::

    mv example_com.key /etc/nginx/ssl/example_com/

4. Make sure your nginx config points to the right cert file and to the private
   key you generated earlier::

    server {
        listen 443;

        ssl on;
        ssl_certificate /etc/nginx/ssl/example_com/ssl-bundle.crt;
        ssl_certificate_key /etc/nginx/ssl/example_com/example_com.key;

        # side note: only use TLS since SSLv2 and SSLv3 have had recent vulnerabilities
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

        # ...

    }

6. Restart nginx.


.. [1] I purchased mine through Namecheap.com.
.. [2] Based on these instructions: http://goo.gl/4zJc8

rst Erlang / OTP(仮)

Erlang / OTP(仮)

erlang.rst
###############
Erlang/OTP (仮)
###############

:日時: 2016-09-21
:作: @voluntas
:バージョン: 1.0.1
:url: https://voluntas.github.io/

2016 年 6 月 24 日に行われる `BPStudy <http://bpstudy.connpass.com/event/31195/>`_ の発表資料です

概要
====

**この発表では Erlang のソースコードは出てきません**

Erlang/OTP の今と今後について、 Erlang/OTP を使っているユーザの視点からお話をします。

Erlang を知らない人向けのお話もします。ディープな Erlang ユーザの皆さんは退屈だと思いますので、その時は寝ててください。

で、だれ?
==========

@voluntas です。時雨堂という小さい会社を経営しています。 Erlang を書いてご飯を食べたりしています。

最近はリアルタイムな映像配信としての WebRTC を 2 年くらい追いかけてます。

::

    $ git clone git@github.com:erlang/otp.git
    $ ag voluntas


Erlang はどこで使われているの?
===============================

やはりこれが一番気になるところでは無いでしょうか。何ができるとかよりもどんなところで使われているの?というのが自分も知りたいです。

細かい話をすると色々あるので、自分が紹介したいヤツだけ紹介することにします。

LINE
----

一番皆さんに身近な部分だと LINE だと思います。 LINE さんはロードバランサーとアプリケーションサーバの間にいるとのことです。詳しい技術的な話は私もしらないので省略します。

ただ、大規模な例としてとてもわかりやすいかと思います。

- `Adopting SPDY in Line – Part 1: An Overview « LINE Engineers' Blog <http://developers.linecorp.com/blog/?p=2381>`_
- `LINE Corporation | 募集職種一覧 <https://linecorp.com/ja/career/position/458>`_

  - "Java/C、C++/Scala/Erlang中に一つ以上の言語に対する強い(extensive/strong)の力量および経験"

ドワンゴ
--------

日本で Erlang の活躍を世に広めたと言っても過言ではないとおもいます。話を聞くとかなり大規模なレベルで Erlang を使用しています。

- `なぜErlangにしたのか <http://sile.github.io/slide/kbkz_tech_03/#/>`_
- `【ニコニコ事業】大規模コンテンツ配信システム開発エンジニア C++/Erlang(正社員)|募集職種一覧|採用情報|株式会社ドワンゴ <https://progres05.jposting.net/pgdwango/u/job.phtml?job_code=966>`_

  - Erlangでの開発経験が1年以上ある方

WhatsApp
--------

Erlang を使用しているときに一番取り上げられますが、日本ではいまいちメジャーではないので難しいです。 WhatsApp は Facebook に買収された LINE のようなサービスと考えてもらえれば良いです。

彼らはコアのシステムを全て Erlang で作っています。ユーザ数は 10 億ユーザを超えています。

League of Legends
-----------------

個人的に熱いのが LoL というオンラインゲームのチャットシステムに採用された話です。LoL は 5 対 5 に分かれて戦うオンラインのゲームです。

同時接続 7000 万人を支える基盤として採用されています。1 日 2700 万プレイヤー。秒間 11000 メッセージだそうです。

- `How League of Legends Scaled Chat to 70 million Players - It takes Lots of minions. - High Scalability - <http://highscalability.com/blog/2014/10/13/how-league-of-legends-scaled-chat-to-70-million-players-it-t.html>`_

Heroku
------

昔はルーティングメッシュと呼ばれていした。簡単に言うと一番前にいるインテリジェンスなルーターです。
リクエストが来たらどの Dyno に送るかどうかを判断している部分です。

- `Stuff Goes Bad: Erlang in Anger <https://engineering.heroku.com/blogs/2014-09-17-erlang-in-anger/>`_

Game of War
-----------

知ってる人は知っている、スマートフォンアプリのゲームです。人気もかなりあります。ここを開発している Machine Zone は基盤に Erlang を使っています。

- `MZ - Senior Software Engineer, Core Platform <https://jobs.lever.co/machinezone/01807073-3176-457c-9259-342d5b10f0cd>`_

  - Experience with writing production-quality software in Erlang OTP, highly scalable & concurrent systems a double plus

Pinterest
---------

Erlang ではなく Elixir の例もせっかくなので。 Pinterest は Python の会社ですが、 Java で書かれたシステムの一部を Elixir で置き換えたようです。

- `Introducing new open-source tools for the Elixir community | Pinterest Engineering <https://engineering.pinterest.com/blog/introducing-new-open-source-tools-elixir-community>`_
- `Why Pinterest just open-sourced new tools for the Elixir programming language | VentureBeat | Dev | by Jordan Novet <http://venturebeat.com/2015/12/18/pinterest-elixir/>`_


Erlang を検討する
=================

さて、 Erlang を検討するというのは何を持ってして検討するといいのでしょうか。

Erlang を採用する最大の理由は安定性です。 OS 側のトラブルに巻き込まれたのを含まれない限り私がお手伝いしたサーバのほとんどで大変安定した動作をしています。

私が関わったので、話ができる内容ではユーザ数が最低でも数百万人を支えている認証や課金基盤では 2 年以上、特に障害が無く安定して稼働しています。

Erlang を実際に使っている人達のほとんどが安定性が欲しくて採用しています。

性能は?
--------

1 秒で 100 万リクエストを 1 つの TCP から送られた場合は処理できません。これは Erlang が軽量プロセスモデルを採用しており、さらに軽量プロセス 1 つの性能限界があるからです。

Erlang を選択した場合のほとんどがミドルウェアの開発になるのですが、上記で書いたように一定以上を超えると性能に限界がきます。残念ながら C/C++ で書かれたミドルウェアに性能は勝てません。

Erlang は一つのプロセスに負荷が集中するような処理は一定以上になると弱くなります。軽量プロセスで裁ける処理はがんばっても秒間 50000 メッセージ前後という認識です。

また暗号処理などの計算量が必要になるものは遅いです。 LINE や WhatsApp でもメッセージ経路が暗号化されていますが、その部分は C/C++ で書かれた TLS 終端を前段に置いています。

貴方が作ろうとしている何かが、計算処理が必要になるのであれば Erlang を採用するのは間違いです。

生産性は?
----------

人に寄ります。ただ私にとって、サーバやミドルウェアを Python で書くよりは遙かに開発がしやすいです。ただウェブアプリを書くのには向いていませんので、ウェブアプリを書く場合は Elixir を検討すべきでしょう。

性能がつらくなってきても Erlang にしがみついている人のほとんどは開発効率や安定性が高いというのを実感しているからというのはあると思います。ただこれは残念ながら個人の感想です。

開発者は?
----------

Erlang は独特な文法のため採用がしづらいと言われますが、慣れだと思います。慣れました。

また、初めての人でもそんなに大変ではありません。 Erlang 自体はとても簡単です。難しいのは綺麗にシステムを設計する部分ですが、これはどの言語を使っても同じじゃ無いでしょうか。

Erlang を学ぶ
=============

さて、 Erlang を学びたくなった場合どうするのがいいのでしょうか。

日本語で学びたい場合は良い本がでているのでそれを読むのが最適です。

- `プログラミング Erlang <https://estore.ohmsha.co.jp/titles/978427406714P>`_
- `すごい Erlang ゆかいに学ぼう! <https://estore.ohmsha.co.jp/titles/978427406912P>`_

まずはこの二冊を買えば間違いはありません。順番としてはプログラミング Erlang から読み始めていってください。

ただ、 `プログラミング Erlang`_ は古いです。それだけ注意してください。ただ Erlang という言語を学ぶのにはとても良いです。プログラミング Erlang を読み終えて、まだ Erlang を学ぶ意欲があれば `すごい Erlang ゆかいに学ぼう!`_ を読みましょう。おなかいっぱいになるはずです。

本は良著が二冊あるので、正直困りません。実際に書き始めたらどうせドキュメントとソースがお友達になります。

作りたいものがない人へ
----------------------

Erlang は独特の言語なので学ぶだけで実際に仕事や何かに使う必要が無くても考え方が面白いと思います。

とりあえず学んでみるもとてもよい選択です。

作りたいものがある人へ
----------------------

それが Web アプリなら Elixir + Phoenix + Ecto を検討しましょう。 Erlang はウェブアプリを作るのに大変向いていません。できないの?と言われたらできます。ただしお勧めしません。

Elixir は私は残念ながら書いたこと無いのですが、 Erlang VM 上で動く言語ということで Erlang VM の恩恵を受けることは可能です。落ちにくいウェブアプリを作ることができるでしょう。

Web アプリ以外であれば、いくつかのソースを参考にしていくと良いと思います。 RabbitMQ や ejabberd などはよく使われるサーバですし、とても良い教材です。

まずは Erlang の場合はプロセスをどう配置するかという設計が重要になってくるので、既存のプロダクトのソースを読むというのはとても良い選択になります。

Erlang の現状
=============

Erlang ですが歴史はそこそこ古いです。1986 年に登場しました。生まれてない人もいたりするのではないでしょうか。 OSS になったのは 1998 年です。


Erlang は GitHub 上で開発されています。それもかなり早い段階で GitHub の採用を決めました。また最近は機能追加なども全て GitHub 上でやりとりされ Pull-Request ベースになりました。

バグ一覧も公開されています。 http://bugs.erlang.org/projects/ERL

実は Erlang はついこの間まで EPL という独自のライセンスでした。MPL ライクなライセンスです。しかし最近 APL 2.0 に切り替えられました。

Erlang はエリクソンが開発し保有する言語だったのですが、今はかなり開かれており活発に開発されています。

時代に乗り遅れないための機能を追加したりしつつも、新しいチャレンジもしています。

リリース
--------

Erlang のロードマップは年に 2 回ほど Erlang 関連のカンファレンスで発表されます。

安定的なリリースも Erlang の魅力の一つかもしれません。

今後の Erlang
=============

今年の 6/22 に Erlang/OTP 19 がでました。このリリースはとても大きなリリースです。

**ざっくり書いてます**

- 暗号周りが大幅に書き換わりました
- 外部接続用の関数が 3~5 倍速くなりました
- 軽量プロセスのメッセージキューのハンドリングが設定できるようになりました

多くの機能が追加されてパフォーマンスも向上しています。また既存の Erlang に対する不満を解決してくれています。

Erlang/OTP 18 で時刻が入り、マップが正式版になり恩恵を受けた人もちらほらいるでしょう。
ただし 19 はそれ以上に大きな効果をもたらしてくれます。性能が課題になっていた部分もなんとかなる部分もあります。

Erlang は安定的なリリースを行ってきています。大きな変更がある場合は RC 版がでます。またユーザ数の割にドキュメントやテストが大変充実しています。

Erlang ユーザはなぜかドキュメントやテストを書く習慣を持っている人が多いです。不思議です。

Erlang ユーザ達
===============

若い人も居ますが、 50 ~60 代の人も沢山います。自分が一番驚いたのはかなり年配のエンジニアが現役で居続けていることです。日本だとすでに 35 最低年説で引退していないと行けない年齢です。

私が彼らと話した印象は、彼らが Erlang の専門家であることは間違いないのですが、それよりも他の沢山の事の専門家でした。私も Erlang を書いては居ますが、専門が Erlang かと言われるとノーです。 Erlang は私の専門を使ってプロダクトを作るための道具なのです。

彼らは道具としての Erlang を使い続けている熟達者という印象でした。ネットワークの専門家もいれば、広告の専門家もいて、いろいろな専門家の人が Erlang のユーザという印象でした。

Erlang をとりまく環境
=====================

エディタ
--------

基本は Emacs です。最近は VIM も頑張っていますし IDE も頑張っています。正直何でもイイと思います。

貴方が普段使っているのを使えば良いです。

rebar3
------

Erlang はビルドツールが不在で基本 Makefile で頑張るというのでしたが rebar というビルドツールがでてから世界が変わりました。

rebar はアップデートして rebar3 になり、いまは Erlang の公式ビルドツールとしてリポジトリも erlang/rebar3 に置いてあります。

基本的には rebar3 を使えば良いのですが、色々問題が出たりもします。そのときは slack や GitHub issues で相談すれば良いと思います。ソースは黒魔術的なのが多いのでツライかもしれません。

hex
---

大変遠回りをした感じはありますが Elixir のおかげで、 Erlang には公式のパッケージマネージャーが登場しました。

`Hex <https://hex.pm/>`_ です。これは Elixir の恩恵を Erlang が受けているとても良い例です。

Erlang で戦う
=============

Erlang を採用すると決めた場合に課題となるのはメンテナンスでしょうか。人に依存するために会社がいやがる事はおおいでしょう。最終的には判断をするのは偉い人です。そこはキモに命じておきましょう。

一番良い材料はさっさと Erlang でプロトタイプを作ってしまう事です。これができるのであれば一番です。

それが難しい場合は、貴方の情熱が全てです。

また珍しいパターンもあって会社の方針で Erlang や Elixir を採用するというパターンもあります。この場合一番良いのは Erlang や Elixir に詳しい人にお手伝いを依頼することです。

私自身いくつかの会社の Erlang のお手伝いをしています。お手伝い内容は基本的な書き方から始まり運用、設計方針まで相談を受けられます。宣伝になってしまうかもしれませんが、最初から知っている人がいるというのは大変大きいです。

Erlang で戦うということは Erlang を追いかけるということです。

Erlang を追いかける
===================

一番手っ取り早いのが otp/erlang のコミットログと Pull-Request を読む事です。また Erlang メーリングリストの bugs を追いかけるのも良いでしょう。

最近は slack ができたのでそこを見てるだけでもおなかいっぱいになります。

さて、よく言われるのが日本語の情報がないという事ですが、ある一定までは最初の方に紹介した本で十分です。

それ以降は英語を駆使して GitHub などを見て貰う必要があります。公式ドキュメントも翻訳はされていません。英語はある程度はできる前提の言語という認識で良いと思います。

ユーザ数が少ない事もあると思いますが、英語での情報がある前提の世界だと思って頂いて良いです。それがツライ場合は選択しないのが賢明です。

最近はちらちら日本語情報がでていていますし、貴方が日本語の情報発信者になるのも良いでしょう。 Elixir 関連では翻訳も出てきていますし、 Elixir 本の翻訳もオーム社が行っており、夏頃発売する予定です。

Erlang の強さ
=============

落ちにくい
----------

Erlang の強さですが、大変落ちにくいというのが一番です。自分はいろいろなシステムを作ってきましたがとにかく落ちにくいです。

5 年以上前に 1 度だけロングラン負荷試験の最中に Erlang VM の GC バグを引いてセグフォで落ちました。これ以外ではメモリーリークのある VM を引いたくらいしかありません。メモリーリークはすぐに VM をアップデートしたら解決しました。

クラッシュさせる
----------------

よく言われる何かあったらクラッシュさせればいいと言われますが、確かにそうです。
ただちょっと違うのは **別に正常系だけ書けばいい** というわけではありません。

何かあったらクラッシュさせるというのは **想定外のエラーがきたとのためになんでもかんでも try/catch しなくていい** というのが正しいです。

想定内範囲のエラーはキッチリ対応すべきです。そしてエラーも丁寧に書くべきでしょう。想定外のエラーが起きたときは Erlang VM が丁寧なクラッシュログを残してくれているのでそれを見ましょう。そして **想定内のエラー** としてコードを修正しましょう、そのときにテストを書くのを忘れずに。

基本非同期
----------

Erlang はメッセージパッシングを使うことですべて非同期で処理することができます。つまり別の計量プロセスに対して処理を依頼して、結果が戻ってくるかどうかは依頼したプロセス次第と言うことです。もちろん待つこともできます。

Erlang では基本的に非同期で実装して、同期にできそうなところだけ同期にしていきます。ここが Erlang プログラミングのキモだと私は思っています。


性能を測る
==========

Erlang は早い言語ではありません。ボトルネックが色々あります。そこを解決できるように負荷試験を気軽にできるようにしましょう。

プロファイラから始まり軽量プロセスの情報を取得したりといった Erlang ベタベタなスキルから、負荷試験のノウハウという Erlang が関係ない部分の知識も必要になります。

Erlang にはプロファイラが 3 種類はいっていますし、VM の情報を気軽に取ることができます。

常にボトルネックを見つけられるようにしておくのはとても良い事です。

テストを書く
============

Erlang を使う場合ほとんどがネットワークサーバの開発になると思います。その場合は EtoE のテストを気軽にできる恩恵を受けるのが良いでしょう。

Erlang のテストでは自分自身をサーバとして起動し、クライアントからの実際のネットワークテストなども簡単にできます。さらにカバレッジも取れます。これらをビルドサーバに組み込み、常に EtoE テストができるようにすることも大事です。


rst 设置Django,nginx和uwsgi

设置Django,nginx和uwsgi

gistfile1.rst
This document has now been incorporated into the uWSGI documentation:: 

	http://uwsgi-docs.readthedocs.org/en/latest/tutorials/Django_and_nginx.html


******************************
Set up Django, nginx and uwsgi
******************************

Steps with explanations to set up a server using:

* virtualenv
* Django
* nginx
* uwsgi

Concept
=======

nginx will face the outside world. It will serve media files (images, CSS, etc) directly from the file system. However, it can't talk directly to Django applications; it needs something that will run the application, feed it requests from the web, and return responses.

That's uwsgi's job. uwsgi will create a Unix socket, and serve responses to nginx via the uwsgi protocol - the socket passes data in both directions::

    the outside world <-> nginx <-> the socket <-> uwsgi

Before you start
================

virtualenv
----------

Make sure you are in a virtualenv - you will install a system-wide uwsgi later.

Django
------

I am assuming Django 1.4. It automatically creates a wsgi module when you create a project. If you're using an earlier version, you will have to find a Django wsgi module for your project.

Note that I'm also assuming a Django 1.4 project structure, in which you see paths like::

	/path/to/your/project/project/

(i.e. it creates nested directories with the name of your project). Adjust the examples if you using an earlier Django.

It will also be helpful if you are in your Django project's directory. If you don't have one ready, just create a directory for now.

About the domain and port
-------------------------

I'll call your domain example.com. Substitute your own FQDN or IP address.

Throughout, I'm using port 8000. You can use whatever port you want of course, but I have chosen this one so it doesn't conflict with anything a web server might be doing already.

Basic uwsgi intallation and configuration
=========================================

Install uwsgi
-------------

::

pip install uwsgi

Basic test
----------

Create a file called test.py::

	# test.py
	def application(env, start_response):
	    start_response('200 OK', [('Content-Type','text/html')])
	    return "Hello World"

Run::

	uwsgi --http :8000 --wsgi-file test.py

The options mean:

http :8000
	use protocol http, port 8000 

wsgi-file test.py
	load the specified file

This should serve a hello world message directly to the browser on port 8000. Visit::

	http://example.com:8000

to check.                       

Test your Django project
------------------------

Now we want uwsgi to do the same thing, but to run a Django site instead of the test.py module.

But first, make sure that your project actually works! Now you need to be in your Django project directory.

::

	python manage.py runserver 0.0.0.0:8000

Now run it using uwsgi::

	uwsgi --http :8000 --chdir /path/to/your/project --module project.wsgi --virtualenv /path/to/virtualenv

The options mean:

chdir /path/to/your/project
	use your Django project directory as a base
module project.wsgi
	i.e. the Python wsgi module in your project
virtualenv /path/to/virtualenv
	the virtualenv

There is an alternative to using the `--module` option, by referring instead to the wsgi *file*::

wsgi-file /path/to/your/project/project/wsgi.py
	i.e. the system file path to the wsgi.py file


Point your browser at the server; if the site appears, it means uwsgi can serve your Django application from your virtualenv. Media/static files may not be served properly, but don't worry about that.

Now normally we won't have the browser speaking directly to uwsgi: nginx will be the go-between.

Basic nginx
===========

Install nginx
-------------

The version of Nginx from Debian stable is rather old. We'll install from backports.

::

	sudo pico /etc/apt/sources.list     # edit the sources list

Add::

	# backports
	deb http://backports.debian.org/debian-backports squeeze-backports main

Run::

	sudo apt-get -t squeeze-backports install nginx	# install nginx
	sudo /etc/init.d/nginx start	# start nginx

And now check that the server is serving by visiting it in a web browser on port 80 - you should get a message from nginx: "Welcome to nginx!"

Configure nginx for your site
-----------------------------

Check that your nginx has installed a file at `/etc/nginx/uwsgi_params`. If not, copy http://projects.unbit.it/uwsgi/browser/nginx/uwsgi_params to your directory, because nginx will need it. Easiest way to get it::

	wget http://projects.unbit.it/uwsgi/export/3fab63fcad3c77e7a2a1cd39ffe0e50336647fd8/nginx/uwsgi_params

Create a file called nginx.conf, and put this in it::

	# nginx.conf
	upstream django {
	    # connect to this socket
	    # server unix:///tmp/uwsgi.sock;	# for a file socket
	    server 127.0.0.1:8001;	# for a web port socket 
	    }
 
	server {
	    # the port your site will be served on
	    listen      8000;
	    # the domain name it will serve for
	    server_name .example.com;	# substitute your machine's IP address or FQDN
	    charset     utf-8;
   
	    #Max upload size
	    client_max_body_size 75M;	# adjust to taste

	    # Django media
	    location /media  {
			alias /path/to/your/project/project/media;	# your Django project's media files
	    }
   
		location /static {
			alias /path/to/your/project/project/static;	# your Django project's static files
		}
   
	    # Finally, send all non-media requests to the Django server.
	    location / {
	        uwsgi_pass  django;
	        include     /etc/nginx/uwsgi_params; # or the uwsgi_params you installed manually 
	        }
	    }

Symlink to this file from /etc/nginx/sites-enabled so nginx can see it::

	sudo ln -s ~/path/to/your/project/nginx.conf /etc/nginx/sites-enabled/

Basic nginx test
----------------

Restart nginx::

	sudo /etc/init.d/nginx restart

Check that media files are being served correctly:

Add an image called media.png to the /path/to/your/project/project/media directory

Visit 

http://example.com:8000/media/media.png     

If this works, you'll know at least that nginx is serving files correctly.

nginx and uwsgi and test.py
===========================

Let's get nginx to speak to the hello world test.py application.

::

	uwsgi --socket :8001 --wsgi-file test.py

This is nearly the same as before, except now we are not using http between uwsgi and nginx, but the (much more efficient) uwsgi protocol, and we're doing it on port 8001. nginx meanwhile will pass what it finds on that port to port 8000. Visit:

http://example.com:8000/

to check.

Meanwhile, you can try to have a look at the uswgi output at:

http://example.com:8001/

but quite probably, it won't work because your browser speaks http, not uwsgi.

Using sockets instead of ports
==============================

It's better to use Unix sockets than ports - there's less overhead.

Edit nginx.conf. 

uncomment
	server unix:///tmp/uwsgi.sock;
comment out
	server 127.0.0.1:8001;

and restart nginx.

Runs uwsgi again::

	uwsgi --socket /tmp/uwsgi.sock --wsgi-file test.py

Try http://example.com:8000/ in the browser.

If that doesn't work
--------------------

Check your nginx error log(/var/log/nginx/error.log). If you see something like::

	connect() to unix:///path/to/your/project/uwsgi.sock failed (13: Permission denied)

then probably you need to manage the permissions on the socket (especially if you are using a file not in /tmp as suggested).

Try::

	uwsgi --socket /tmp/uwsgi.sock --wsgi-file test.py --chmod-socket=644 # 666 permissions (very permissive)

or::

	uwsgi --socket /tmp/uwsgi.sock --wsgi-file test.py --chmod-socket=664 # 664 permissions (more sensible) 

You may also have to add your user to nginx's group (probably www-data), or vice-versa, so that nginx can read and write to your socket properly.                                         

Running the Django application with uswgi and nginx
===================================================

Let's run our Django application::

	uwsgi --socket /tmp/uwsgi.sock --chdir /path/to/your/project --module project.wsgi --virtualenv /path/to/virtualenv --chmod-socket=664

Now uwsgi and nginx should be serving up your Django application.


a uwsgi .ini file for our Django application
============================================

Deactivate your virtualenv::

	deactivate

and install uwsgi system-wide::

	sudo pip install uwsgi
                                                             
We can put the same options that we used with uwsgi into a file, and then ask uwsgi to run with that file::

	# django.ini file
	[uwsgi]

	# master
	master			= true

	# maximum number of processes
	processes 		= 10

	# the socket (use the full path to be safe)
	socket          = /tmp/uwsgi.sock 

	# with appropriate permissions - *may* be needed
	# chmod-socket    = 664

	# the base directory
	chdir           = /path/to/your/project 

	# Django's wsgi file
	module          = project.wsgi

	# the virtualenv 
	home            = /path/to/virtualenv

	# clear environment on exit
	vacuum          = true           


And run uswgi using the file::

	uwsgi --ini django.ini

Note:

--ini django.ini
	use the specified .ini file

Test emperor mode
=================

uwsgi can run in 'emperor' mode. In this mode it keeps an eye on a directory of uwsgi config files, and spawns instances ('vassals') for each one it finds. 

Whenever a config file is amended, the emperor will automatically restart the vassal.

::

	# symlink from the default config directory to your config file
	sudo ln -s /path/to/your/project/django.ini /etc/uwsgi/vassals/

	# run the emperor as root
	sudo uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data --master

The options mean:

emperor /etc/uwsgi/vassals
	look there for vassals (config files)
uid www-data
	run as www-data once we've started
gid www-data
	run as www-data once we've started

Check the site; it should be running. 

Make uwsgi startup when the system boots
========================================

The last step is to make it all happen automatically at system startup time.

Edit /etc/rc.local and add::

	/usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data --master

before the line "exit 0".

And that should be it!

rst 如何在OS X上安装omake

如何在OS X上安装omake

how-to-install-omake-on-osx.rst
============================
How to install omake on OS X
============================

::

  brew update && brew upgrade
  brew install opam


::

  opam init
  eval `opam config env`


::

  opam install batteries core


::

  opam show omake


::

  opam update
  opam install omake

rst 使用Nginx安装Comodo PositiveSSL证书的步骤。

使用Nginx安装Comodo PositiveSSL证书的步骤。

install-comodo-ssl-cert-for-nginx.rst
Setting up a SSL Cert from Comodo
=================================

I use `Namecheap.com <http://www.namecheap.com/?aff=83780>`_ as a registrar, and they resale
SSL Certs from a number of other companies, including `Comodo <http://www.comodo.com/>`_.

These are the steps I went through to set up an SSL cert.

Purchase the cert
-----------------

Prior to purchasing a cert, you need to generate a private key, and a CSR file
(Certificate Signing Request). You'll be asked for the content of the CSR file
when ordering the certificate.

::

    openssl req -new -newkey rsa:2048 -nodes -keyout example_com.key -out example_com.csr

This gives you two files:

* ``example_com.key`` -- your Private key. You'll need this later to configure ngxinx.
* ``example_com.csr`` -- Your CSR file.

Now, purchase the certificate [1]_, follow the steps on their site, and you should soon get an 
email with your *PositiveSSL Certificate*. It contains a zip file with the following:

* Root CA Certificate - `AddTrustExternalCARoot.crt`
* Intermediate CA Certificate - `COMODORSAAddTrustCA.crt`
* Intermediate CA Certificate - `COMODORSADomainValidationSecureServerCA.crt`
* Your PositiveSSL Certificate - `www_example_com.crt` (or the subdomain you gave them)

Install the Commodo SSL cert
----------------------------

Combine everything for nginx [2]_:

1. Combine the above crt files into a bundle (the order matters, here)::

    cat www_example_com.crt COMODORSADomainValidationSecureServerCA.crt  COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > ssl-bundle.crt

2. Store the bundle wherever nginx expects to find it::

    mkdir -p /etc/nginx/ssl/example_com/
    mv ssl-bundle.crt /etc/nginx/ssl/example_com/

3. Ensure your private key is somewhere nginx can read it, as well.::

    mv example_com.key /etc/nginx/ssl/example_com/

4. Make sure your nginx config points to the right cert file and to the private
   key you generated earlier::

    server {
        listen 443;

        ssl on;
        ssl_certificate /etc/nginx/ssl/example_com/ssl-bundle.crt;
        ssl_certificate_key /etc/nginx/ssl/example_com/example_com.key;

        # side note: only use TLS since SSLv2 and SSLv3 have had recent vulnerabilities
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

        # ...

    }

6. Restart nginx.


.. [1] I purchased mine through Namecheap.com.
.. [2] Based on these instructions: http://goo.gl/4zJc8