泥泞的沼泽

PHP,Python,Mac,Linux,Web

Gentoo下使用Grub2

| Filed under Linux

Gentoo的官方文档里, 很早就写的是如何使用grub来启动Gentoo, 然而grub2已经出来很长一段时间了, 可是文档却一直没有更新. 这里, 给大家介绍一下如何在Gentoo下使用Grub2.

  1. 安装Grub2
    emerge grub

  2. 将Grub2装到MBR上
    grub2-install /dev/sda

  3. 将内核的名字改成vmlinuz--, 比如我的写成了vmlinuz-3.8.10-gentoo, 然后生成配置文件
    grub2-mkconfig -o /boot/grub2/grub.cfg

  4. 重启机器即可

将你的Fedora升级到开发版

| Filed under Fedora Linux

在Fedora开发当中, 有一个词你可能经常见到, 那就是rawhide. rawhide的意思是最新版, 就是说, 如果目前最新的Fedora是18的话, 那么rawhide就是19. 如果Fedora哪天升到了19, 那么rawhide就是20.

最为一个Fedora的开发者或者Packager, 将自己的Fedora升级到rawhide是个很不错的选择.

照着做吧:

  1. yum install fedora-release-rawhide
  2. 修改/etc/yum.repos.d/fedora-rawhide.repo, 将enabled=0改成enabled=1, 然后将这个目录下的其它.repo里的enabled=1都改成enabled=0.
  3. yum distro-sync
  4. reboot

Done! 你得到了rawhide版的Fedora!

使用Intellij IDEA从零使用Spring MVC

| Filed under Java

黑了Java这么多年, 今天为Java写一篇文章吧.

这篇文章主要是想帮助那些刚接触到Java, 同时想从事Java WEB GUI开发的人. 对我而言, 我很早就有想尝试用Java写WEB的想法, 可是没有一次成功过, 不管是用struts, 还是纯JSP, 总是配置不好, tomcat不能正确的运行我的程序.

自打那以后, 我一直在抱怨Java的application, 尤其是要部署于tomcat的, 太难了, 太复杂了. 而且还没有什么文档是专门讲这个, 全部都是讲如何用eclipse配置SSH, 然后开发, 然后部署. 对于一个不想使用eclipse的人, 简直无从下手.

好了, 不多说废话了, 今天我要讲的是Srping MVC的使用和tomcat的部署, 以及如何用maven来管理dependency. 我用的工具是Intellij IDEA, 不过我会说明程序的目录结构是什么样的, 这样不管你用什么IDE, 都可以参考.

  1. 建立一个空的java项目, 在select type那里, 选择maven module, 项目名字什么的, 随便起一个
  2. 在下一个页面里, 什么都不改, 什么都不选, 点finish
  3. 默认打开了pom.xml, 这个是maven的配置文件, 为了让程序能够自动倒入spring mvc和jsp, selvlet等的依赖, 我们在里面加入如下配置:

    <properties>
        <java-version>1.7</java-version>
        <org.springframework-version>3.1.3.RELEASE</org.springframework-version>
    </properties> 
    <dependencies> 
        <!-- Spring -->
        <dependency> 
            <groupId>org.springframework</groupId> 
            <artifactId>spring-context</artifactId> 
            <version>${org.springframework-version}</version> 
        </dependency> 
        <dependency> 
            <groupId>org.springframework</groupId> 
            <artifactId>spring-webmvc</artifactId> 
            <version>${org.springframework-version}</version> 
        </dependency> 
    
        <!-- servlet jsp and jstl -->
        <dependency> 
            <groupId>javax.servlet</groupId> 
            <artifactId>javax.servlet-api</artifactId> 
            <version>3.0.1</version> 
            <scope>provided</scope> 
        </dependency> 
        <dependency> 
            <groupId>javax.servlet.jsp</groupId> 
            <artifactId>jsp-api</artifactId> 
            <version>2.0</version> 
            <scope>provided</scope> 
        </dependency> 
        <dependency> 
            <groupId>javax.servlet</groupId> 
            <artifactId>jstl</artifactId> 
            <version>1.2</version> 
        </dependency> 
    </dependencies>
    
  4. 等待Intellij自动导入里面写的包

  5. 确保我们有一个跟src目录平级的web目录, 然后在里面简历一个目录叫WEB-INF. 说到这里, 就要说一下tomcat的webapp目录结构了. 首先要有一个WEB-INF目录, 然后在WEB-INF里, 有classes目录: 存放所有代码的目录; lib目录: 存放所有jar文件; web.xml文件, 存放webapp的配置.
  6. 编辑web.xml文件, 改成如下内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
             version="3.0">
    <!-- Handles all requests into the application -->
    <servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    </web-app>
    

    这段的内容, 是将url跳转到appServlet配置里, 在appServlet的配置里, 使用servlet-context.xml.

  7. servlet-context.xml内容如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/mvc
    
    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
    
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    
    <!-- Scans the classpath of this application for @Components to deploy as beans -->
    <context:component-scan base-package="me.davidx.LearnJava" />
    
    <!-- Configures the @Controller programming model -->
    <mvc:annotation-driven />
    
    <!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
    </bean>
    </beans>
    

    这段的大概意思是, 自动扫描包”me.davidx.LearnJava”来找到controller定义. 同时, controller都使用@Controller来定义. bean里的定义, 表明所有的View文件都到/WEB-INF/views目录来找, 后缀都为.jsp.

  8. 在me.davidx.LearnJava包里, 定义一个HomeController类, 这里给一个范例:

    package me.davidx.LearnJava.controllers;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class HomeController {
        @RequestMapping("/home")
        public String home(Model model) {
            model.addAttribute("message", "hello, world");
            //return "WEB-INF/views/home.jsp";
            return "home";
        }
    }
    
  9. 看完了controller的定义, 我们再来看看view文件: home.jsp:

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <%@ page session="false" %>
    <html>
    <head>
        <title>Home</title>
    </head>
    <body>
        <h1><c:out value="${message}"/></h1>
        <h2>Again!</h2>
    </body>
    </html>
    

    这里使用了jstl, 以前写过jsp的童鞋, 应该一看就明白了.

  10. 代码工作都完成啦, 下面就是部署了.
by davidx | tags : | 1

毕业这五年

| Filed under Uncategorized

今天看到别人写毕业五年的总结, 才发现, 原来我也毕业五年了. 弹指一挥间, 在IT这个行业, 也摸爬滚打了4年了.

记得初中时接触Basic, 觉得这是很好玩的东西, 然后立志以后要成为一个优秀的程序员. 高中时对编程有些疏远, 倒是有些迷恋游戏. 大学的专业不是计算机, 自然不会受到一些专业的技能培训了, 当然了, 知识培训也没有. 毕业时, 也是远离了所有IT类的工作, 那个时候的我, 认为现在的IT都是苦逼的封闭开发, 除了吃饭就是写程序.

在非IT类工作混了一年后, 发现自己还是对开发感兴趣, 毅然的回到了IT的行业里, 从基本的PHP开发做起. 刚进这个行业的时候, 对IT只是有很浅的认识, 连PHP基本的语法, 都不是很了解. 但是自认为动手能力比较强, 由于没有什么经验, 很多公司都不愿意要我, 甚至有家公司在我完全做出了他们的面试题后, 都不愿意要我, 让我很是郁闷. 这个时候, 只有诺赛肯收留我, 所以我还是很感谢这个公司的.

PHP的工作我只做了2年, 然后就去Platform做了1年多的Python. 再然后的事情就是Platform被IBM收购, 然后我成为了IBM的员工, 由于项目需要, 我又开始做起了Java, 这个让我黑了很久的语言.

回想起搞IT的这几年, 发现自己的技术增长, 有一些畸形. 看起来貌似懂很多, 其实都是皮毛, 因为没有做过C的开发, 对很多底层的东西, 都是一知半解. 所以, 如果有想长期从事这个行业的童鞋, 一定不要忽视技术细节和底层实现, 你可以不去写, 但是不能不了解. 举个很简单的例子, 写过编译器的人, 对程序优化, 是不是手到擒来? 如果没有能力去写, 那么去了解一下, 也要比光盯着语言层面去优化, 要顺手很多?

零零星星写了这么多, 就当是一个简单的总结吧.

by davidx | tags : | 1

SSL通信详解

| Filed under Uncategorized

通信加密

这里我们先确定几个角色, 李雷, 韩梅梅和班主任. 班主任为了防止早恋, 不允许异性说话, 李雷和韩梅梅交流只能通过信件. 于是, 李雷给韩梅梅写了一封信, 信件在传输过程中, 被班主任截获到了. 班主任看到了信的内容后, 批评了李雷.

李雷在受到批评后, 问韩梅梅, 我们怎么防止班主任截获到我们信件的内容呢? 韩梅梅建议用加密的方式, 即李雷写完信以后, 用密钥A加密, 韩梅梅收到信后, 用密钥A解密. 如此反复几次之后, 班主任算出了密钥A, 成功的将信件的内容破解, 李雷再次受到了批评.

再次收到批评后, 李雷和韩梅梅想到了另外一个方法来加密信件: 即, 李雷用公钥A将信件加密, 韩梅梅用私钥B解密, 公钥A私钥B是一对密钥, 其它密钥均无法解密信件内容. 班主任拿到公钥A也无法解密信件, 而私钥B则不会到班主任手中.

班主任的方法

班主任发现无法解密信件后, 想了很久, 发现可以用如下的方法破解: 班主任自己生成了一套密钥公钥A'私钥B'. 在李雷向韩梅梅询问公钥A的时候, 班主任冒充韩梅梅, 将密钥A'给了李雷, 李雷用公钥A'加密信件后, 将信寄出, 班主任得到信件后用私钥B'解密, 成功得到信件内容, 李雷又一次受到了批评.

身份的验证

连续的批评, 让李雷意识到, 只要公钥远远不够, 还要验证对方是不是韩梅梅. 那么, 如何证明给李雷公钥的是韩梅梅本人而不是班主任呢? 李雷想到了让Uncle Wang来做证明. Uncle Wang告诉李雷提供公钥的是韩梅梅本人而不是别人的时候, 李雷就放心的用公钥加密信件了, 信件再也没有让班主任解密过了.

实际的概念

上面的故事, 实际就是通信的过程中, 加密/解密/认证的过程. 客户端要给服务器端发送信息, 首先会先向服务器请求公钥A, 其次会在得到公钥A后将加密数据并发送过去. 服务器端收到数据后, 会用私钥B解密, 得到真正的数据. 整个加密过程, 实际上就是非对称加密了. 客户端和服务器有不同的密钥, 第三方获取到任何数据后, 都无法解密得到需要的信息.

但是这里并不能解决身份验证的问题, 即, 未经验证的服务器给了客户端公钥A', 就会得到客户端发送的数据了. 解决这个问题的方法有两种:

  1. 使用第三方认证机构来认证, 即, 建立连接时, 去第三方询问, 该服务器是否是自己想要访问的服务器
  2. 检查自己的仓库里, 是否有对方的认证, 如果有, 是否对的上

经过了上面的步骤后, 客户端已经可以确认服务器的身份了, 于是开始使用公钥A, 后面的过程前面已经说过了, 就不再重复了.

SSL的认证, 实际就是这么一个过程, 使用证书来验证对方的身份, 使用公钥来加密数据, 使用私钥来解密数据. 证书公钥, 都是由服务器来提供给客户端使用的, 私钥是服务器自己使用来解密数据的. 证书, 公钥私钥, 均由服务器生成.

一般来说, 证书公钥是放在一起的, 叫认证, 一起给对方, 英文叫Certificate.

by davidx | tags : | 2

JS模板和JSON数据的结合

| Filed under JavaScript

Web2.0的开发里, ajax是一个非常重要的技术. 如果你的网站里没有点ajax做的东西, 你都不好意思说你是web2.0的网站.

使用ajax的时候, 最关心的就是数据传输的格式了, 一般来说, 有以下几种格式:

  1. 纯文本
  2. HTML代码
  3. XML
  4. JSON

可以说主流的就是上面几种了. 下面我们来分别分析一下:

  1. 纯文本
    使用纯文本的格式, 可以传输一些message类的文本, 用于在前台页面显示. 优点是简单, 缺点是功能少.

  2. HTML代码
    将页面结构和数据放在一起返回给页面, 前台拿到后, 可以不需要任何处理就显示在页面上, 使用简单. 优点是无需处理, 缺点是页面结构和数据都由后台提供, 页面的结构发生变化后, 需要去改后台脚本.

  3. XML
    使用XML作为数据的格式, 结构化非常明显, 功能更加丰富了, 各种各样的数据结构都可以支持了. 优点是数据结构化, 缺点是处理繁琐, 前台使用需要将数据和HTML结构拼接在一起, 使用比较复杂. 同时, XML本身的缺点是数据量大.

  4. JSON
    JSON有着和XML一样的结构化的优势, 同时由于JSON没有关闭标签的概念, 所以JSON的数据量比XML小很多. 有统计数据说平均能少46%, 虽然这个数字我不相信, 但是我相信肯定会少很多. 优点是数据结构化, 缺点是前台同样需要将JSON里的数据和页面结构拼接在一起, 使用比较复杂.

那么, 虽然XML和JSON有些优秀的结构化的优势, 功能会更多的优势, 可是又有前台难处理的缺点, 该如何取舍呢? 其实, 我们可以换一种思路, 既然问题出在数据和HTML结构拼接的时候, 一会写HTML代码, 一会写数据, 这么麻烦, 为什么, 不用模板来替我们做这个事情呢? 哈哈, 我的真正观点来了, 那就是, 要使用JS模板来解决这个问题!

继续使用JSON来传输数据, 得到数据后, 不直接与HTML结构结合, 而是通过模板一次性套好页面, 现在浏览器的JS引擎都很给力, 所以不会有任何性能问题! 一举两得!

这里只给一个简单的例子让大家看明白即可:

<!DOCTYPE html>
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
</head>
<body>

<ul id="movieList"></ul>

<script>
  var movies = [
  { Name: "The Red Violin", ReleaseYear: "1998" },
  { Name: "Eyes Wide Shut", ReleaseYear: "1999" },
  { Name: "The Inheritance", ReleaseYear: "1976" }
  ];

var markup = "<li><b>${Name}</b> (${ReleaseYear})</li>";

/* Compile the markup as a named template */
$.template( "movieTemplate", markup );

/* Render the template with the movies data and insert
   the rendered HTML under the "movieList" element */
$.tmpl( "movieTemplate", movies )
  .appendTo( "#movieList" );
</script>

</body>
</html>

这个例子很简单, 甚至没有写ajax, 但是大家可以用ajax来得到类似movies变量的数据, 然后传给template, 就可以了. 这样比起传HTML数据, 优势很明显:

  1. 传输的数据量少, 只有JSON数据.
  2. 页面生成在前台, 修改的时候, 不需要修改和重启后台程序.
  3. 前台处理的时候, 模板成为重点, HTML结构由模板控制, 修改方便.

创建一个干净的开发/测试环境

| Filed under GIT Linux

我以前开发的时候, 总是习惯在本地创建一个开发环境, 同时也可以测试, 但是时间长了发现, 这样会有一些问题, 比如你的环境和生成环境总有一些不同, 比如你开发用mac, 可是mac上装python的包, 没有linux方便, 你可能会遇到各式各样的问题. 总之, 遇到这样的问题的时候, 你可能会说, 还是linux好, 没有这些问题, 可是linux的UX体验, 又没有mac或者windows好.

那么, 我们怎么办呢? 现在很多开发者都流行将开发/测试环境, 放进虚拟机里. 虚拟机一般就是一个只有CLI的linux主机, 比如debian/arch/gentoo种种你喜欢的, 顺手的版本. 你可以将你所有需要的开发包, 都装在上面, 本地只要一个git客户端和编辑器就够了, 甚至连git都放进虚拟机里好了, 本地只用一个编辑器就好了. 需要测试的时候, 直接ssh连到虚拟机, 或者web项目测试的时候, 直接通过浏览器访问虚拟机就可以了. 这样, 你的机器更加的干净, 开发环境出现问题, 无法恢复的时候, 直接删掉虚拟机重新建立就可以了!

然后呢, 我们要怎么办呢? 我的代码在本地, 还是在虚拟机里呢? 我更倾向于把代码放在本地, 然后通过samba共享, 或者vbox的共享, 共享到虚拟机里做测试. 开发环境出现问题了, 恢复的时候, 本地的代码可以完全不受影响.

by davidx | tags : | 7

产品开发的一点点想法

| Filed under 代码段

代码段的前身叫大卫粘贴, DavidPaste, 是一个代码粘贴的工具, 做了大概有几个月, 上线后一直作为工具来用, 并没有什么流量和收入. 然后因为工作, 很长一段时间都没有再开发和维护, 又由于服务器的原因, DavidPaste甚至都不能访问了. 再后来公司的项目做完了, 自己终于有时间了, 才拿过来继续开发, 朋友给了我一个更好的域名, 就是现在的daimaduan.com.

改名为代码段后, 网站的架构发生了很大的变化. 后台的框架从django到web.py再到flask, 数据库现在是用的postgresql, 其它的东西, 基本也都是python里主流的库了, 没有什么特别的东西了.

自己做产品了, 发生这条路是条不归路, 需要很大的毅力, 才能把它坚持下来. 断断续续做了2-3年, 总结了一些经验, 分享给大家:

1. Design很重要. 对产品的设计, 其实就是对产品的定位. 定位很重要, 定位不明确, 很有可能会把自己陷入两难的境界, 很难再跟别人竞争.

2. 技术选型问题. 很多开发者, 热衷于新技术或者熟悉的技术, 在选型上有很大的个人喜好. 我的看法是, 技术选型, 应该是按需选择, 合适的工具做合适的事情, 才是一个好的架构师应该做的事情. 不要刻意选择某种技术, 实用, 是第一位的. 现在做产品, 都讲究快速迭代, 快速让产品上线, 是很重要的. 技术新鲜与否, 其实并不重要. 另外就是, 不要过度`过早的优化, 等遇到性能问题了, 再去优化, 也来的及, 而且也来的实际.

3. 代码质量. 自己做开发了, 没有公司所有的流程了, 没有各种限制了, 很多人就认为可以随意写了, 实际上这个时候, 更应该注意质量了. 文档, 测试, bug追踪, 一个都不能少. 不要因为是自己开发, 把什么都放脑子里, 写下来, 还是有好处的. 测试是重中之重, 你写出来的东西, 给别人用的时候, 有bug, 是很致命的. 很多用户, 遇到明显的bug后, 首先会对你的产品产生质疑, 无论你提供了多好的功能, 一个bug都可能把整个产品毁掉.

4. 界面. 产品的界面, 就是产品的一张脸. 脸漂亮了, 就能更好的吸引用户. 但是漂亮是因人而异的, 所以, 不要期望你的界面艳丽到所有人都会喜欢, 大多数人喜欢了, 就可以了.

5. 功能的添加. 一个产品, 不可能没有功能的添加. 多听取用户的建议, 添加一些大多数用户需要的功能, 是很必要的. 这也是对产品的改进, 最关键的一步.

最后想要说的是, 自己的产品, 就像自己的孩子, 大家都是爱的. 可是这个时候, 不要太偏执了, 要广泛听取用户的建议和看法, 毕竟你的产品, 是给大家用的. 没有一个产品, 是一次性就满足所有人的需求的, 都是需要渐进式的改进的.

by davidx | tags : | 2

Java下使用SSL连接

| Filed under Java

在Java下使用SSL的连接的文章很多了, 我就不多说了, 这里着重说一下SSL连接的一些重要概念, 让大家知道自己都在干什么.

1. 认证的问题. 认证一共有2种, 服务器端认证和客户端认证. 这两种认证有什么区别呢? 服务器端认证是给客户端用的, 作用是告诉客户端, 我是可以信任的服务器. 客户端认证是给服务器端用的, 作用是告诉服务器端, 这个客户端是可以信任的客户端.

2. 一次握手和两次握手. 一次握手, 意思是, 客户端只需要验证服务器即可, 即, 该服务器是否是需要连接的服务器, 而不是一个假冒的服务器. 那么两次握手呢? 就是在一次握手的基础上, 再验证一次客户端. 服务器端需要保证, 连接在这个服务器的客户端, 是允许访问的客户端, 而不是假冒的.

3. Java对认证的使用. 一般情况下, 用Java来做SSL连接, 首先需要保证服务器端的认证, 在没在JVM的可信任认证里, 如果不在, 则拒绝与服务器的连接. 这时, 就需要keytool工具了. keytool是Java提供的管理认证和Key的工具. 在我们得到一个服务器端的认证后, 使用keytool -import -alias -file

这里有一段测试代码可以供大家参考, http://daimaduan.com/paste/view/1016

by davidx | tags : | 0

使用uWSGI部署你的程序

| Filed under Python

关于uWSGI, 大家可以自行去查阅, 资料很多. uWSGI基本上可以理解为一个独有的协议, 支持python, php, ruby等脚本, 比fcgi效率更高, 目前还处于开发活跃期.

尽管如此, 使用uWGSI部署程序, 还是值得信赖,  尤其是它的效率, 实在是不错!

开始介绍部署之前, 我们先来看看一般开启uWSGI, 都需要调哪些参数:

-M 开启Master进程

-p 4 开启4个进程

-s 使用的端口或者socket地址

-d 使用daemon的方式运行, 注意, 使用-d后, 需要加上log文件地址, 比如-d /var/log/uwsgi.log

-R 10000 开启10000个进程后, 自动respawn下

-t 30 设置30s的超时时间, 超时后, 自动放弃该链接

–limit-as 32 将进程的总内存量控制在32M

于是, 我们开启uwsgi进程的命令, 就是uwsgi -s /tmp/uwsgi.sock -t 30 -M -p 4 –limit-as 128 -R 10000 -d /var/log/uwsgi.log

可是, 我们这样开启uwsgi后, 并没有给出任何application, 也就没有任何应用部署上去, 我们还可以加一个参数–vhost, 让它支持多application的部署, 这样, 我们在nginx中就可以设置多个application的部署了.

我们再来看一下在nginx中, 怎么配置多application:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
	listen 80;
	server_name example.com;
 
	access_log /var/sites/example.com/access_log main;
	error_log /var/sites/example.com/error_log info;
 
	root /var/sites/example.com/;
 
	location / {
		include uwsgi_params;
		uwsgi_pass unix:///tmp/uwsgi.sock;
		uwsgi_param UWSGI_PYHOME /var/sites/example.com/;
		uwsgi_param UWSGI_SCRIPT moin;
		uwsgi_param UWSGI_CHDIR /var/sites/example.com/;
		uwsgi_param SCRIPT_NAME /;
		uwsgi_param SERVER_NAME example.com;
		uwsgi_modifier1 30;
	}
}

多个application的话, 写多个server即可.
主要讲讲location中的东西.

  1. 注意导入uwsgi_params, 这个不能少
  2. UWSGI_PYHOME和UWSGI_CHDIR都是项目的目录, 要记得写到最终执行的脚本那层
  3. SCRIPT_NAME一般写/就行了
  4. UWSGI_SCRIPT这个, 要写最终执行的脚本名字, 该脚本一定要是.py结尾的, 比如moin.py, 但是在这里写moin, 省略.py.

都写好后, 就可以重启nginx了, 我们的应用就部署好了. 我这个例子是moinmoin的部署.

像moinmoin和django, 可以使用–vhost的参数, 然后做多应用共享一个uwsgi进程的处理, 可是flask就不行了, 每一个flask application, 必须单独享用一个uwsgi进程. 我们先从uwsgi的命令看起:

uwsgi-2.6 -s :9001 -M -p 4 -R 512 –limit-as 32 -d /var/sites/example.com/uwsgi.log -t 30 –file /var/sites/example.com/start.py –callable app

start.py里放的一个app的定义, 比如:

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python
#-*-coding:utf-8-*-
from flask import Flask
 
app = Flask(__name__)
 
@app.route('/')
def index():
     return 'hello, flask!'

这里需要注意的就是, 不要有app.run()这样的代码出现.
然后我们再去看nginx的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
	listen 80;
	server_name example.com;
 
	access_log /var/sites/example.com/access_log main;
	error_log /var/sites/example.com/error_log info;
 
	root /var/sites/example.com/;
 
	location / {
		include uwsgi_params;
		uwsgi_pass 127.0.0.1:9001;  
	}
 
}

怎么样, 这种方式部署的话, nginx的配置比较简单吧. 这时, 我们开启uwsgi, 同时加载该nginx配置, 就可以了!