精华内容
下载资源
问答
  • Nameko [nah-meh-koh]用于Python的微服务框架,可让服务开发人员专注于应用程序逻辑并鼓励可测试性。 Nameko服务只是一类:#来自nameko.rpc的helloworld.py imp Nameko [nah-meh-koh] Python的微服务框架,可让服务...
  • Python构建无服务器微服务 这是Packt发布的“用的代码库。 适用于开发人员,DevOps和架构师的使用Python开发端到端无服务器微服务的实用指南。 这本书是关于什么的? 在过去的几年中,由于它们的小而独立的部署...
  • Flask是Python高手公认的、好用的轻量级框架,内核+各种扩展插件,能让你轻松灵活的应对各种大小项目的开发,这次,在纯实战的生产环境中,给你讲透Flask,让你达到实际工作1.5年以上的水平。
  • jive-sdk-python-pip 用于为Python PIP构建微服务和Jive附加组件的有用工具 要安装,请使用以下命令: pip install jive_sdk 有关如何使用此库的示例,请查看
  • nameko:用于构建微服务Python框架
  • Python构建、测试、部署和扩展微服务 本文为 Python Microservices Development 的选择性翻译,本书暂时无中文版,有能力请直接看原版 什么是微服务? A microservice is a lightweight application, which ...

    用Python构建、测试、部署和扩展微服务

    本文为 Python Microservices Development 的选择性翻译,本书暂时无中文版,有能力请直接看原版

    什么是微服务?

    A microservice is a lightweight application, which provides a narrowed list of features with a well-defined contract. It's a component with a single responsibility, which can be developed and deployed independently.

    微服务是一个轻量级的应用程序,它通过定义良好的契约提供窄范围的特性列表。 它是一个具有单一职责的组件,可以独立地进行开发和部署。

    本书内容:
    第一章 理解微服务,定义什么是微服务,以及在现在web应用当中的角色.说明为什么Python非常适合构建微服务。
    第二章 了解Flask,介绍Flask的主要特性。用Flask搭建一个简单的web应用微服务。
    第三章 编码,文档,和测试——良性循环,描述测试驱动和持续集成方法,Flask应用构建和打包实践 第四章 设计Runnerly,通过应用的功能和用户故事,解释如何将他建成一个整体应用,然后把它分解成微服务,并解释它们如何与数据进行交互。还将介绍Open API 2.0 规范(ex-Swagger),该规范可用于藐视HTTP APIs。
    第五章 整合其他服务,解释一个服务如何与后端服务整合,怎样处理网络分割和其他交互问题,以及如何在隔离状态下测试服务。
    第六章 服务安全,解释如何保护你的微服务,以及如何处理用户身份严重「」服务到服务身份验证和用户管理。还将介绍欺诈和滥用,以及如何将他们降低。 第七章 监控你的服务,解释如何在你的代码中添加日志和指标(metrics),以及如何确保你对你的应用程序中正在发生的事情有一个清晰的全局理解,从而跟踪问题并了解你的服务使用情况。
    第八章 整合起来,描述了如何设计和构建一个使用了微服务的JavaScript应用程序,给终端用户界面。 第九章 打包运行Runnerly,描述如何打包、构建和运行整个Forrest应用程序。作为一名开发人员,能够将构成应用程序的所有部分运行到单个开发包中是必不可少的。
    第十章 集装箱式服务,解释什么是虚拟化,如何使用Docker,以及如何将你的服务进行Dockerize。
    第十一章 在AWS上部署,介绍现有的云服务提供商,和AWS世界,展示了如何实例化服务器,对于运行微服务的应用程序非常有用的AWS服务。本文还介绍了CoreOS,一个专门为在云中部署Docker容器而创建的Linux发行版。
    第十二章 下一步是什么,在书的结尾处给出了一些关于如何独立于特定的云供应商和虚拟化技术构建微服务的建议,以避免将所有鸡蛋放在同一个篮子里。它强调了你在第九章中学到的东西,打包和运行Runnerly。

    单体应用的利弊:

    • 可能是开始一个项目最简单的方式
    • 集中式数据库简化了数据的设计和组织。
    • 部署一个应用程序很简单。
    • 代码中的任何更改都可能影响不相关的特性。当某个功能出现问题时,整个应用程序都可能出现问题。
    • 扩展应用程序的解决方案是有限的:你可以部署多个实例,但是如果应用程序中的一个特定功能占用了所有资源,那么它就会影响到所有方面。
    • 随着代码库的增长,很难保持它的整洁和受控。

    一个酒店预订网站的结构

    1. 单体应用结构

    2. 微服务结构

    1. 在这个设计中,每个组件都使用 HTTP 协议进行通信,并且特性可以通过 RESTful web 服务获得。
    2. 没有集中的数据库,每个微服务在内部处理自己的数据结构,进出的数据使用语言无关的格式,如 JSON。

    微服务优点

    1. 关注点分离

      • 首先,每个微服务都可以由一个独立的团队独立开发。 例如,构建一个预订服务本身就是一个完整的项目。 负责团队可以使用任何编程语言和数据库,只要它有一个良好文档的 HTTP API。
      • 这也意味着相比单体应用,程序的进化更好地受到控制。例如,如果支付系统改变了与银行的底层交互,那么影响就局限在该服务内部,而应用程序的其余部分保持稳定,可能不会受到影响。
      • 这种松散耦合大大提高了整体项目的速度,因为我们在服务层面采用了类似于单一责任原则的理念
    2. 需要处理的是较小项目

      • 第二个好处是打破了项目的复杂性。 当向应用程序添加一个特性(如 PDF 报告)时,即使做得干净利落,也会使基本代码变得更大、更复杂,有时还会变慢。
      • 在单独的应用程序中构建这个特性可以避免这个问题,并且可以使用任何你想要的工具更容易地编写它。 你可以经常重构它,缩短发布周期,能够更好的掌控。程序的增长仍在控制之下。
      • 在改进应用程序时,处理较小的项目也可以降低风险: 如果团队想要尝试最新的编程语言或框架,他们可以快速迭代一个原型,实现相同的微服务 API,尝试它并决定是否仍然使用它
      • 一个真实的例子是 Firefox Sync 存储微服务。 目前有一些试验从当前的 Python + MySQL 实现切换到基于 go 的实现,该实现将用户的数据存储在独立的 SQLite 数据库中。 这个原型是高度试验性的,但是因为我们已经用一个定义良好的 HTTP API 将存储特性分离到微服务中,所以很容易用一小部分用户尝试一下。(看来有时间还是要学习一下Go)
    3. 更多的扩展和部署选项

      • 最后,将应用程序分割成组件,可以更容易地根据约束进行扩展。 假设你有很多客户每天预定酒店,而生成PDF消耗大量cpu。这时可以将这个特定的微服务部署到拥有更大 cpu 的服务器上。
      • 另一个典型的例子是 RAM 消耗型的微服务,比如那些与内存数据库(如 Redis 或 Memcache)交互的服务。 您可以调整部署,将其部署到具有更少 CPU 和更多 RAM 的服务器上。

    因此,我们可以将微服务的好处概括如下:

    • 一个团队可以独立开发每个微服务,使用任何能使用的技术栈。 他们可以自定义一个发布周期,只需要完成一个与语言无关的 HTTP API。
    • 开发人员将应用程序的复杂性分解为逻辑组件。每个微服务都专注于做好一件事情。
    • 由于微服务是独立的应用程序,因此对部署有更好的控制,这使得扩展更加容易。

    微服务体系结构有助于解决应用程序开始增长时可能出现的许多问题。 然而,我们需要意识到它带来的一些新问题。

    微服务隐患

    1. 不合逻辑的分割
      • 微服务架构的第一个问题是如何设计它。一个团队不可能在第一次就想出完美的微服务架构。 一些微服务(如 PDF 生成器)是显而易见的用例。而只要是处理业务逻辑,你的代码就有很大的可能,在你理解如何将应用分割成正确的微服务集合之前,四处移动。
      • 成熟的设计需要一些尝试和失败的循环。 添加和删除微服务可能比重构单体应用程序更痛苦。
      • 如果分隔不明显的话,可以避免分割应用成微服务
      • 如果有任何怀疑分割有无意义,就保持在一起。将一些代码分割成一个新的微服务,比在合并回两个微服务要容易得多
      • 例如,如果你总是必须将两个微服务部署在一起,或者一个微服务中的一个更改影响到另一个微服务的数据模型,那么您没有正确地分割应用程序,并且这两个服务应该重新组合。
    2. 更多的网络交互
    3. 数据存储和共享
      • 一个有效的微服务需要独立于其他微服务,理想情况下不应该共享一个数据库。 这对我们的酒店预订应用程序意味着什么?
      • 同样,这也引出了很多问题,比如:我们是在所有数据库中使用相同的用户 id,还是在每个服务中使用独立的id并将其作为一个隐藏的实现细节?
      • 一旦用户添加到系统中,我们是通过数据抽取策略在其他服务数据库中复制一些它的信息,还是这样做有点过了?
      • 如何处理数据删除?
      • 尽可能避免数据重复,同时将微服务隔离开来,是设计基于微服务的应用程序的最大挑战之一。

    这些都是很难回答的问题,有很多不同的方法可以解决这些问题,我们将在书中学到这一点。

    1. 兼容性问题

      • 另一个问题发生在功能更改影响多个微服务时。如果更改以向后不兼容的方式影响在服务之间传输的数据,那么就会遇到麻烦。
      • 你部署的新服务是否可以与其他服务的旧版本一起使用?还是需要同时更改和部署多个服务?这是否意味着你发现了一些服务应该被合并回来?
    2. 测试

      • 最后,当你想要进行一些端到端测试并部署整个应用程序时,您现在必须处理许多应用。你需要一个健壮的、敏捷的部署流程来提高效率。你需要能够在开发整个应用程序时使用它。你不可能仅仅用几个用例就完全测试出来。
      • 介绍一些促进微服务的工具

    WSGI标准

    WSGI 最大的问题在于它的同步性。你在前面的代码中看到的应用程序函数对每个传入请求只调用一次,当函数返回时,它必须返回响应。 这意味着每次调用函数时,它都会阻塞,直到响应准备好为止。

    WSGI 服务器将允许你运行一个线程池来同时处理多个请求。 但是你不能运行成千上万个这样的服务,一旦这个池用完了,下一个请求就会阻止客户的访问,而你的微服务什么也不做,只是空闲地等待后端服务的响应。

    这就是为什么 Twisted 和 Tornado 这样的非 wsgi 框架( 在JavaScript 领域中是node.js),非常成功的原因——它完全是异步的。

    在编写 Twisted 应用程序时,可以使用回调来暂停和恢复生成响应的工作。 这意味着你可以接受新的请求并开始处理它们。 这种模式显著地减少了进程中的空闲时间。 它可以处理成千上万的并发请求。 当然,这并不意味着应用程序会更快地返回每个响应。 它仅仅意味着一个进程可以接受更多的并发请求,并且在数据准备发回时在这些请求之间进行切换。

    WSGI 标准没有简单的方法来引入类似的东西,社区已经争论了多年来达成共识---- 但失败了。 可能的情况是,社区最终会放弃 WSGI 标准。
    与此同时,如果你考虑到WSGI标准,一个请求等于一个线程,那么构建具有同步框架的微服务仍然是可能的并且完全没问题。

    但是,有一个增强同步 web 应用程序的技巧—— Greenlet,将在下一节解释。

    Gevent

    Gevent提供了 socket 模块的合作版本,该模块使用 greenlets 来在socket中有数据可用时自动暂停和恢复执行。 甚至还有一个 monkey 补丁功能,可以用 Gevent 的版本自动替换标准库socket。 这使你的标准同步代码在每次使用 socket时都神奇地异步——只需多加一行:

    from gevent import monkey
    
    monkey.patch_all()
    
    
    def application(environ, start_response):
        headers = [('Content-type', 'application/json')]
        start_response('200 OK', headers)
        # ...do something with sockets here...
        return result
    复制代码

    不过,这种隐式的魔力是有代价的。 为了让 Gevent 能够正常工作,所有的底层代码都需要与 Gevent 所做的修补兼容。 一些来自社区的软件包会因为这个原因而继续阻塞甚至产生意外的结果---- 特别是,如果他们使用 c 扩展,并绕过了标准库 Gevent 补丁的一些特性。 但在大多数情况下效果都很好。 与 Gevent 兼容的项目被称为绿色项目。

    Twisted and Tornado

    如果你正在构建微服务,而且并发请求的数量很重要,那么放弃WSGI标准是很诱人的,你可以使用异步框架Twisted 或 Tornado

    import time
    import json
    from twisted.web import server, resource
    from twisted.internet import reactor, endpoints
    
    
    class Simple(resource.Resource):
        isLeaf = True
    
        def render_GET(self, request):
            request.responseHeaders.addRawHeader(b"content-type",
                                                 b"application/json")
            return bytes(json.dumps({'time': time.time()}), 'utf8')
    
    site = server.Site(Simple())
    endpoint = endpoints.TCP4ServerEndpoint(reactor, 8080)
    endpoint.listen(site)
    reactor.run()
    复制代码

    虽然 Twisted 是一个非常健壮和高效的框架,但是它在构建 HTTP 微服务时遇到了以下几个问题:

    • 您需要使用从Resource类派生的类来实现微服务中的每个端点,并实现每个受支持的方法。对于一些简单的API,它添加了许多样板代码。
    • 由于其异步性质,扭曲的代码很难理解和调试。
    • 当你链接太多连续依次触发的函数时,很容易陷入回调地狱 - 代码可能变得混乱。
    • 正确测试Twisted应用程序很困难,您必须使用特定于Twisted的单元测试模型。

    Tornado 基于类似的模型,但在某些领域做得更好。它有一个更轻的路由系统,并尽一切可能使代码更接近普通的Python。 Tornado也使用回调模型,因此调试很困难。 依赖 Python 3中引入的新的异步特性。两个框架都在努力弥合这一问题。

    asyncio

    from aiohttp import web
    import time
    
    
    async def handle(request):
        return web.json_response({'time': time.time()})
    
    
    if __name__ == '__main__':
        app = web.Application()
        app.router.add_get('/', handle)
        web.run_app(app)
    
    复制代码

    但是,基于Python 3的异步框架和库仍然在不断涌现,如果使用异步或aiohttp之类的框架,则需要针对每个需要的特性坚持使用特定的异步实现。 如果需要在代码中使用非异步的库,则从异步代码使用它意味着如果要防止阻塞事件循环,则需要执行一些额外的、具有挑战性的工作。

    如果你的微服务处理的资源数量有限,这可能是可控的。 但是在写这篇文章的时候,坚持使用已经存在了一段时间的同步框架而不是异步框架可能是一个更安全的选择。 让我们享受成熟软件包的现有生态系统,并等待异步生态系统变得更加完善。

    这本书的第二版很有可能使用异步框架。 但是对于这个版本,我们将在整本书中使用 Flask 框架。

    语言性能

    当然,每个人都知道Python比Java或GO慢,但是执行速度并不总是最优先考虑的。微服务通常是一层很薄的代码,其生命周期的大部分时间都在等待来自其他服务的一些网络响应。与从 Postgres 服务器返回 SQL 查询的速度相比,它的核心速度通常不那么重要,因为后者占用了响应的大部分时间。

    但是想要一个尽可能快的应用程序是合理的

    Python 社区中关于加速语言的一个有争议的话题是,GIL如何破坏性能,因为多线程应用程序不能使用多个进程。

    GIL 有存在的充分理由。它保护CPython解释器中非线程安全的部分,并且存在于其他语言中,如 Ruby。到目前为止,所有试图删除它的尝试都未能生成更快的 CPython 实现。

    对于微服务,除了防止在同一进程中使用多个内核之外,GIL 在高负载时会稍微降低性能,因为互斥锁引入了系统调用开销。

    然而,围绕 GIL 的所有审查都是有益的: 在过去几年中已经完成了减少解释器中 GIL 争论的工作,并且在某些方面,Python 的性能有了很大的提高。

    请记住,即使核心团队删除 GIL,Python 也是一种解释语言和垃圾收集语言,并且会因为这些属性而遭受性能损失。

    在静态编译语言中编写一个类似的函数将大大减少产生相同结果所需的操作数量。

    不过,有一些方法可以提高 Python 的执行速度。

    一种方法是通过构建 c 扩展,或者使用语言的静态扩展(如 Cython (http: / / Cython. org /) ,将部分代码编写到已编译的代码中,但这会使代码更加复杂。

    另一个解决方案是最有希望的,那就是使用 PyPy 解释器(http: / / PyPy. org /)简单地运行应用程序。

    Pypy 实现一个实时(JIT)编译器。 这个编译器在运行时直接用 CPU 可以直接使用的机器代码替换部分 Python 代码。 对于 JIT 来说,整个技巧就是要在执行之前提前检测到什么时候以及如何去做。

    即使PyPy总是CPython之后的几个Python版本,但它已经达到了可以在生产中使用的程度,而且它的性能相当惊人。 我们在 Mozilla 的一个项目需要快速执行,PyPy 版本几乎和 Go 版本一样快,所以我们决定在那里使用 Python。 ... 无论如何,对于大多数项目来说,Python 及其生态系统的好处大大超过了本节描述的性能问题,因为微服务的开销很少成为问题。 如果性能有问题,微服务方法允许你重写性能关键组件,而不会影响系统的其余部分。

    在本章中,我们比较了单体应用和微服务的方法来构建 web 应用程序,很明显,这不是一个二元世界,你不是必须在第一天就选择一种方法并一直使用它。

    你应该将微服务视为一个单体应用程序的改进。 随着项目的成熟,服务逻辑的一部分应该迁移到微服务中。 正如我们在本章学到的,这是一个有用的方法,但是要小心谨慎,以免落入一些常见的陷阱。

    Flask

    1. 不同类型的测试

      • 单元测试: 确保一个类或一个函数独立地工作
      • 功能测试: 从使用者的角度验证微服务是否言行一致,即使对于错误请求,微服务也能正确运行
      • 集成测试: 验证微服务如何与其所有网络依赖项集成
      • 负载测试: 测量微服务性能
        • 当我的服务承受压力时,它是 RAM 还是主要受 cpu 限制?
        • 是否可以添加相同服务的其他实例并横向扩展?
        • 如果我的微服务调用其他服务,可以使用连接池,还是必须通过一个连接序列化所有的交互?
        • 服务能一次运行多天而不降级吗?
        • 服务在使用高峰期之后是否正常工作?
      • 端到端测试: 验证整个系统是否与端到端测试一起工作
      • 总结:
        • 功能测试是要编写的最重要的测试,并且通过在测试中实例化应用程序并与之交互,很容易在 Flask 中完成这项工作
        • 单元测试是一个很好的补充,但是不要滥用模拟
        • 集成测试类似于功能测试,但是与真正的部署相对立
        • 负载测试对于了解微服务瓶颈和规划下一步非常有用
        • 端到端测试需要使用客户端通常使用的相同 UI
    2. 使用 WebTest

    3. 使用 pytest 和 Tox

      • pytest自动发现和运行项目中的所有测试
      • Tox python多版本测试
    4. 开发者文档

    5. 持续整合

    展开全文
  • Rhino是用于构建RESTful Web服务python微框架。 安装 从pypi: $ pip install rhino 从git checkout: $ git clone https://github.com/trendels/rhino.git $ cd rhino $ python setup.py install 要运行测试...
  • 学习使用Python和FastAPI构建自己的微服务 如何运行? 确保已安装docker和docker-compose 运行docker-compose up -d 有关电影服务文档的信息,请访问 ;有关演员表服务文档的信息,请访问 。
  • 除此之外,使用Connexion将使你在Python中开发API变得更加流畅。Google在收购Apigee时强调了应用程式界面在当今应用程序架构中的重要性。使用具有精心设计的API微服务对于保持业务成功至关重要,因为它简化了复杂...
  • 用于构建Web应用的Python微框架,快速搭建自己的开发平台!
  • Python Flask 构建微电影视频网站

    千次阅读 2018-09-28 14:26:00
    学会flask的部署方法、安装编译Nginx服务、安装编译Python3.6服务、安装MySQL服务以及通过Nginx反向代理对视频流媒体限制下载速率、限制单个IP能发起的播放连接数;   ...

      “轻”是Flask的精髓,小型项目快速开发,大型项目毫无压力

    • 1-1 课程导学及介绍
    • 1-2 Windows环境搭建
    • 2-2 Mac OS环境搭建
    • 2-3 第一Flask程序
    • 3-1 项目分析及会员登录
    • 3-2 标签-电影-上映预告数据模型设计
    • 3-3 评论-收藏-权限-管理员-操作日志数据模型设计
    • 4-1 前台布局-会员登录页面搭建
    • 4-2 会员注册-会员中心页面搭建
    • 4-3 电影列表-搜索页面搭建
    • 4-4 电影详情页-404页面搭建
    • 5-1 管理员登录-后台布局搭建
    • 5-2 修改密码-控制面板-标签管理页面搭建
    • 5-3 电影管理-上映预告管理页面搭建
    • 5-4 会员-收藏-评论管理页面搭建
    • 5-5 收藏-日志-角色管理页面搭建
    • 5-6 管理员页面搭建
    • 6-1 管理员登录
    • 6-2 标签管理
    • 6-3 电影管理-添加电影
    • 6-4 电影管理-列表、删除、编辑
    • 6-5 预告管理
    • 6-6 会员管理
    • 6-7 评论-收藏管理
    • 6-8 修改密码
    • 6-9 日志管理
    • 7-1 权限管理
    • 7-2 角色管理
    • 7-3 管理员管理
    • 7-4 访问权限控制
    • 8-1 会员注册
    • 8-2 会员登录
    • 8-3 修改会员资料
    • 8-4 修改密码
    • 8-5 会员登录日志
    • 9-1 上映预告-标签筛选-电影分页
    • 9-2 电影搜索-电影详情
    • 10-1 电影评论-统计
    • 10-2 收藏电影
    • 10-3 电影弹幕-代码优化及Bug处理
    • 11-1 CentOS安装LNMP
    • 11-2 部署电影网站-流媒体访问限制

    1-1 课程导学及介绍

    • 学会使用整型、浮点型、路径型、字符串型正则表达式路由转化器;

    • 学会使用post与get请求、上传文件、cookie获取与响应、404处理;

    • 学会使用模板自动转义、定义过滤器、定义全局上下文处理器、Jinja2语法、包含、继承、定义宏;

    • 学会使用Flask-wtf定义表单模型、字段类型、字段验证、视图处理表单、模板使用表单;

    • 学会使用flask-SQLAlchemy定义数据库模型、添加数据、修改数据、查询数据、删除数据、数据库事件、数据迁移;

    • 学会使用蓝图优化项目结构、实现微电影网站前后台业务逻辑;

    • 学会flask的部署方法、安装编译Nginx服务、安装编译Python3.6服务、安装MySQL服务以及通过Nginx反向代理对视频流媒体限制下载速率、限制单个IP能发起的播放连接数;


     

    1-2 Windows环境搭建

    1.2.1 操作系统:Win7;

    1.2.2 编程语言:Python3.6;

    1.2.3 数据库:MySQL5.7;

    1.2.4 虚拟化开发环境:virtualenv;

    1.2.5 IDE:Pycharm; 

    使用豆瓣源安装pip install ,国内镜像地址,速度会快很多。用法:pip install -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com flask

    2-2 MacOS环境搭建

    2.2.1 Python3.6;

    2.2.2 Pycharm2018.3;

    2.2.3 MySQL8.0.12;

    2.2.4 注意pip install flask 以及pip3 install flask的区别;

    2-3 第一Flask程序

    2.3.1 virtualenv的使用;

    • virtualenv venv

    2.3.2 flask的安装;

    • pip3 install flask
    • pip3 freeze
    • deactivate # 退出虚拟化环境

    2.2.3 第一个flask程序的编写;

    • 安装flask==“0.12.2”
    #!/usr/bin/python3
    # -*- coding:utf-8 -*-
    # Project: MicroFilm 
    # Software: PyCharm
    # Time    : 2018-09-28 16:29
    # File    : app.py
    # Author  : 天晴天朗
    # Email   : tqtl@tqtl.org
    from flask import Flask
    
    app = Flask(__name__)
    
    
    @app.route("/")
    def index():
        return "<h1 style = 'color:red'>Hello Flask!</h1>"
    
    
    if __name__ == '__main__':
        app.run()

    3-1 项目分析及会员登录

    3.1.1 项目分析、搭建目录及模型设计;

    3.1.2 前后目录结构分析;

    3.1.3 使用蓝图(蓝本Blueprint)来构建项目目录;

    1)什么是蓝图?

    • 一个应用中或跨应用制作应用组件和支持通用的模式;

    2)蓝图的作用?

    • 将不同的功能模块化;
    • 构建大型应用;
    • 优化项目结构;
    • 增强可读性、易于维护;

    3.1.4 蓝图的使用步骤:

    • 定义蓝图;
    • 注册蓝图;
    • 调用蓝图;

     3.1.5 会员及会员登录日志数据模型设计;

      1)安装数据库连接工具flask-SQLAlchemy(企业级Python的ORM对象关系映射框架,面向对象的思想);

      2)定义MySQL数据库连接基于pymysql+ mysql;

      3)pip3 install flask-sqlalchemy的安装;

     3.1.5 定义数据模型;

    • pip3 install flask-sqlalchemy;

     3.1.6 配置SQLAlchemy;

    SQLAlchemy在线文档:http://www.pythondoc.com/flask-sqlalchemy/config.html

    app/models.py的设计;

    #!/usr/bin/python3
    # -*- coding:utf-8 -*-
    # Project: MicroFilm 
    # Software: PyCharm
    # Time    : 2018-09-28 16:36
    # File    : models.py
    # Author  : 天晴天朗
    # Email   : tqtl@tqtl.org
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    import datetime
    
    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:Tqtl911!@#)^@localhost:3306/MicroFilm/"
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
    
    db = SQLAlchemy(app)
    
    
    class User(db.Model):
        """
        会员表;
        """
        __tablename__ = "user"  # 表名
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 昵称
        pwd = db.Column(db.String(100), unique=True)  # 密码
        email = db.Column(db.String(100), unique=True)  # 邮箱
        phone = db.Column(db.String(11), unique=True)  # 手机号码
        info = db.Column(db.Text)  # 个性简介
        face = db.Column(db.String(255), unique=True)  # 头像
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 注册时间
        uuid = db.Column(db.String(255), unique=True)  # 唯一标识符
        userlogs = db.relationship("UserLog", backref="user")  # 外键关系的关联
    
        def __repr__(self):
            return "<User %r>" % self.name
    
    
    class UserLog(db.Model):
        """
        会员登录日志表
        """
        __tablename__ = "userlog"  # 表名
        id = db.Column(db.Integer, primary_key=True)  # 编号
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 所属会员
        ip = db.Column(db.String(100))  # 登录IP
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 登录时间;
    
        def __repr__(self):
            return "<UserLog %r>" % self.id

    3-2 标签-电影-上映预告数据模型设计

    3.2.1 标签数据模型的设计;

    3.2.2 电影数据模型设计;

    3.2.3 上映预告数据模型的设计;

    app/models.py; 

    #!/usr/bin/python3
    # -*- coding:utf-8 -*-
    # Project: MicroFilm 
    # Software: PyCharm
    # Time    : 2018-09-28 16:36
    # File    : models.py
    # Author  : 天晴天朗
    # Email   : tqtl@tqtl.org
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    from datetime import datetime
    
    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:Tqtl911!@#)^@localhost:3306/MicroFilm/"
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
    
    db = SQLAlchemy(app)
    
    
    class User(db.Model):
        """
        会员表;
        """
        __tablename__ = "user"  # 表名
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 昵称
        pwd = db.Column(db.String(100), unique=True)  # 密码
        email = db.Column(db.String(100), unique=True)  # 邮箱
        phone = db.Column(db.String(11), unique=True)  # 手机号码
        info = db.Column(db.Text)  # 个性简介
        face = db.Column(db.String(255), unique=True)  # 头像
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 注册时间
        uuid = db.Column(db.String(255), unique=True)  # 唯一标识符
        userlogs = db.relationship("UserLog", backref="user")  # 外键关系的关联
    
        def __repr__(self):
            return "<User %r>" % self.name
    
    
    class UserLog(db.Model):
        """
        会员登录日志表
        """
        __tablename__ = "userlog"  # 表名
        id = db.Column(db.Integer, primary_key=True)  # 编号
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 所属会员
        ip = db.Column(db.String(100))  # 登录IP
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 登录时间;
    
        def __repr__(self):
            return "<UserLog %r>" % self.id
    
    
    class Tag(db.Model):
        """
         标签
        """
        __tablename__ = "tag"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 标题
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
        movies = db.relationship("Movie", backref="tag")  # 电影外键关系的关联
    
        def __repr__(self):
            return "<Tag %r>" % self.name
    
    
    class Movie(db.Model):
        """
        电影表
        """
        __tablename__ = "movie"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        title = db.Column(db.String(255), unique=True)  # 标题
        url = db.Column(db.String(255), unique=True)  # 地址
        info = db.Column(db.Text)  # 简介
        logo = db.Column(db.String(255), unique=True)  # 封面
        star = db.Column(db.SmallInteger)  # 星级
        playnum = db.Column(db.BigInteger)  # 播放量
        commentnum = db.Column(db.BigInteger)  # 评论量
        tag_id = db.Column(db.Integer, db.ForeignKey("tag.id"))  # 所属标签
        area = db.Column(db.String(255))  # 上映地区
        release_time = db.Column(db.Date)  # 上映时间
        length = db.Column(db.String(100))  # 播放时间
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return "<Movie %r>" % self.title
    
    
    class Preview(db.Model):
        """
        上映预告表
        """
        __tablename__ = "preview"  # 表名
        id = db.Column(db.Integer, primary_key=True)  # 编号
        title = db.Column(db.String(255), unique=True)  # 标题
        logo = db.Column(db.String(255), unique=True)  # 封面
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return "<Preview %r>" % self.title

    3-3 评论-收藏-权限-管理员-操作日志数据模型设计

    3.3.1 定义评论数据模型;

    3.3.2 定义收藏电影数据模型;

    3.3.3 定义权限数据模型;

    3.3.4 定义角色数据模型;

    3.3.5 定义管理员数据模型;

    3.3.6 定义登录日志操作数据模型;

    3.3.7 定义操作日志数据模型;

     3.3.8 ModuleNotFoundError: No module named 'MySQLdb'报错处理之pip3 install pymysql;

    3.3.9 执行python3 models.py 进行生成数据表操作;

     app/models.py;

    #!/usr/bin/python3
    # -*- coding:utf-8 -*-
    # Project: MicroFilm 
    # Software: PyCharm
    # Time    : 2018-09-28 16:36
    # File    : models.py
    # Author  : 天晴天朗
    # Email   : tqtl@tqtl.org
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    from datetime import datetime
    import pymysql
    
    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:Tqtl911!@#)^@localhost:3306/MicroFilm"
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
    
    db = SQLAlchemy(app)
    
    
    class User(db.Model):
        """
        会员表;
        """
        __tablename__ = "user"  # 表名
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 昵称
        pwd = db.Column(db.String(100), unique=True)  # 密码
        email = db.Column(db.String(100), unique=True)  # 邮箱
        phone = db.Column(db.String(11), unique=True)  # 手机号码
        info = db.Column(db.Text)  # 个性简介
        face = db.Column(db.String(255), unique=True)  # 头像
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)  # 注册时间
        uuid = db.Column(db.String(255), unique=True)  # 唯一标识符
        userlogs = db.relationship("UserLog", backref="user")  # 会员日志外键关联
        comments = db.relationship("Comment", backref="user")  # 评论外键关联
        moviecols = db.relationship("MovieCol", backref="user")  # 收藏外键关联
    
        def __repr__(self):
            return "<User %r>" % self.name
    
    
    class UserLog(db.Model):
        """
        会员登录日志表;
        """
        __tablename__ = "userlog"  # 表名
        id = db.Column(db.Integer, primary_key=True)  # 编号
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 所属会员
        ip = db.Column(db.String(100))  # 登录IP
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)  # 登录时间;
    
        def __repr__(self):
            return "<UserLog %r>" % self.id
    
    
    class Tag(db.Model):
        """
         标签表;
        """
        __tablename__ = "tag"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 标题
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)  # 添加时间
        movies = db.relationship("Movie", backref="tag")  # 电影外键关系的关联
    
        def __repr__(self):
            return "<Tag %r>" % self.name
    
    
    class Movie(db.Model):
        """
        电影表;
        """
        __tablename__ = "movie"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        title = db.Column(db.String(255), unique=True)  # 标题
        url = db.Column(db.String(255), unique=True)  # 地址
        info = db.Column(db.Text)  # 简介
        logo = db.Column(db.String(255), unique=True)  # 封面
        star = db.Column(db.SmallInteger)  # 星级
        playnum = db.Column(db.BigInteger)  # 播放量
        commentnum = db.Column(db.BigInteger)  # 评论量
        tag_id = db.Column(db.Integer, db.ForeignKey("tag.id"))  # 所属标签
        area = db.Column(db.String(255))  # 上映地区
        release_time = db.Column(db.Date)  # 上映时间
        length = db.Column(db.String(100))  # 播放时间
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)  # 添加时间
        comments = db.relationship("Comment", backref="movie")  # 评论外键关系关联
        moviecols = db.relationship("MovieCol", backref="movie")  # 收藏外键关系关联
    
        def __repr__(self):
            return "<Movie %r>" % self.title
    
    
    class Preview(db.Model):
        """
        上映预告表;
        """
        __tablename__ = "preview"  # 表名
        id = db.Column(db.Integer, primary_key=True)  # 编号
        title = db.Column(db.String(255), unique=True)  # 标题
        logo = db.Column(db.String(255), unique=True)  # 封面
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)  # 添加时间
    
        def __repr__(self):
            return "<Preview %r>" % self.title
    
    
    class Comment(db.Model):
        """
        评论表;
        """
        __tablename__ = "comment"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        content = db.Column(db.Text)  # 内容
        movie_id = db.Column(db.Integer, db.ForeignKey("movie.id"))  # 所属电影
        user_id = db.Column(db.Integer, db.ForeignKey("user.id"))  # 所属用户
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)  # 添加时间
    
        def __repr__(self):
            return "<Comment %r>" % self.id
    
    
    class MovieCol(db.Model):
        """
        电影收藏表;
        """
        __tablename__ = "moviecol"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        movie_id = db.Column(db.Integer, db.ForeignKey("movie.id"))  # 所属电影
        user_id = db.Column(db.Integer, db.ForeignKey("user.id"))  # 所属用户
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)  # 添加时间
    
        def __repr__(self):
            return "<MovieCol %4>" % self.id
    
    
    class Auth(db.Model):
        """
        权限表;
        """
        __tablename__ = "auth"
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(100), unique=True)
        url = db.Column(db.String(255), unique=True)
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)
    
        def __repr__(self):
            return "<Auth %r>" % self.name
    
    
    class Role(db.Model):
        """
        角色表;
        """
        __tablename__ = "role"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 名称
        auths = db.Column(db.String(600))  # 权限
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)  # 添加时间
    
        def __repr__(self):
            return "<Role %r>" % self.name
    
    
    class Admin(db.Model):
        """
        管理员表;
        """
        __tablename__ = "admin"  # 表名
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 昵称
        pwd = db.Column(db.String(100), unique=True)  # 密码
        is_super = db.Column(db.SmallInteger)  # 是否为超级管理员,0为超级管理员;
        role_id = db.Column(db.Integer, db.ForeignKey("role.id"))  # 所属角色
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)  # 添加时间
        adminlogs = db.relationship("AdminLog", backref="admin")  # 管理员登录日志
        oplogs = db.relationship("OpLog", backref="admin")  # 操作日志
    
        def __repr__(self):
            return "<Admin %r>" % self.name
    
    
    class AdminLog(db.Model):
        """
        管理员登录日志表;
        """
        __tablename__ = "adminlog"
        id = db.Column(db.Integer, primary_key=True)
        admin_id = db.Column(db.Integer, db.ForeignKey("admin.id"))
        ip = db.Column(db.String(100))
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)
    
        def __repr__(self):
            return "<AdminLog %r>" % self.id
    
    
    class OpLog(db.Model):
        """
        操作日志表;
        """
        __tablename__ = "oplog"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        admin_id = db.Column(db.Integer, db.ForeignKey("admin.id"))  # 所属管理员
        ip = db.Column(db.String(100))  # 登录IP
        reason = db.Column(db.String(600))  # 操作原因
        addtime = db.Column(db.DateTime, index=True, default=datetime.now)  # 创建时间;
    
        def __repr__(self):
            return "<OpLog %r>" % self.id
    
    
    if __name__ == '__main__':
        """
            db.create_all()
        role = Role(
            name="超级管理员",
            auths="",
        )
        db.session.add(role)
        db.session.commit()
        """
        from werkzeug.security import generate_password_hash
    
        admin = Admin(
            name="ImoocMovie1",
            pwd=generate_password_hash("ImoocMovie1"),
            is_super=0,
            role_id=1
        )
        db.session.add(admin)
        db.session.commit()

    4-1 前台布局-会员登录页面搭建

    4.1.1 拷贝前端同事分享的static下的目录文件; 

    4.1.2 templates新增index.html、home.html;

    4.1.3 报错待处理block 后面添加content对象;

    index.html;

    {% extends "home/home.html" %}
    
    {% block content %}
    <h1>Hello Flask!!!</h1>
    {% endblock %}

    home.html;

    <!doctype html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="renderer" content="webkit">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1 , user-scalable=no">
        <title>微电影</title>
        <link rel="shortcut icon" href="{{ url_for('static',filename ='base/images/logo.png') }}">
        <link rel="stylesheet" href="{{ url_for('static',filename ='base/css/bootstrap.min.css') }}">
        <link rel="stylesheet" href="{{ url_for('static',filename ='base/css/bootstrap-movie.css') }}">
        <link rel="stylesheet" href="{{ url_for('static',filename ='base/css/animate.css') }}">
        <style>
            .navbar-brand > img {
                display: inline;
            }
    
        </style>
        <style>
            .media {
                padding: 3px;
                border: 1px solid #ccc
            }
    
        </style>
    </head>
    
    <body>
    <!--导航-->
    <nav class="navbar navbar-default navbar-fixed-top">
        <div class="container">
            <!--小屏幕导航按钮和logo-->
            <div class="navbar-header">
                <button class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a href="index.html" class="navbar-brand" style="width:250px;">
                    <img src="{{ url_for('static',filename = 'base/images/logo.png') }}" style="height:30px;">&nbsp;微电影
    
                </a>
            </div>
            <!--小屏幕导航按钮和logo-->
            <!--导航-->
            <div class="navbar-collapse collapse">
                <form class="navbar-form navbar-left" role="search" style="margin-top:18px;">
                    <div class="form-group input-group">
                        <input type="text" class="form-control" placeholder="请输入电影名!">
                        <span class="input-group-btn">
                            <a class="btn btn-default" href="search.html"><span class="glyphicon glyphicon-search"></span>&nbsp;搜索</a>
                        </span>
                    </div>
                </form>
                <ul class="nav navbar-nav navbar-right">
                    <li>
                        <a class="curlink" href="index.html"><span class="glyphicon glyphicon-film"></span>&nbsp;电影</a>
                    </li>
                    <li>
                        <a class="curlink" href="login.html"><span class="glyphicon glyphicon-log-in"></span>&nbsp;登录</a>
                    </li>
                    <li>
                        <a class="curlink" href="register.html"><span class="glyphicon glyphicon-plus"></span>&nbsp;注册</a>
                    </li>
                    <li>
                        <a class="curlink" href="logout.html"><span class="glyphicon glyphicon-log-out"></span>&nbsp;退出</a>
                    </li>
                    <li>
                        <a class="curlink" href="user.html"><span class="glyphicon glyphicon-user"></span>&nbsp;会员</a>
                    </li>
                </ul>
            </div>
            <!--导航-->
    
        </div>
    </nav>
    <!--导航-->
    <!--内容-->
    <div class="container" style="margin-top:76px">
        {% block content %}{% endblock %}
    </div>
    <!--内容-->
    <!--底部-->
    <footer>
        <div class="container">
            <div class="row">
                <div class="col-md-12">
                    <p>
                        ©&nbsp;2018&nbsp;microfilm.cuixiaozhao.com&nbsp;京ICP备 13046642号-2
                    </p>
                </div>
            </div>
        </div>
    </footer>
    <!--底部-->
    <script src="{{ url_for('static',filename = 'base/js/jquery.min.js') }}"></script>
    <script src="{{ url_for('static',filename = 'base/js/bootstrap.min.js') }}"></script>
    <script src="{{ url_for('static',filename = 'base/js/jquery.singlePageNav.min.js') }}"></script>
    <script src="{{ url_for('static',filename = 'base/js/wow.min.js') }}"></script>
    <script src="{{ url_for('static',filename = 'lazyload/jquery.lazyload.min.js') }}"></script>
    <script src="//cdn.bootcss.com/holder/2.9.4/holder.min.js"></script>
    <script>
        $(function () {
            new WOW().init();
        })
    
    </script>
    <script>
        $(document).ready(function () {
            $("img.lazy").lazyload({
                effect: "fadeIn"
            });
        });
    </script>
    </body>
    </html>

    4.1.4 页面呈现;

    4-2 会员注册-会员中心页面搭建

    4.2.1 定义登录页面的视图函数:login/logout;

    4.2.2 开发index.html,继承home.html并添加{% block content %} {% endblock %}区块;

    4.2.3 home/home.html页面中{{ url_for('home.login') }} 和{{ url_for('home.logout') }}的使用;


    4.2.4 会员注册页面的搭建过程;

     

     4.2.5 会员中心页面搭建;

    4-3 电影列表-搜索页面搭建

    4.3.1 电影列表页面搭建;

    4.3.2 首页index.html呈现;

    4.3.3 电影搜索页面搭建;

    4-4 电影详情页-404页面搭建

    4.4.1 404页面处理;

    4.4.2 404视图函数代码在app/__init__.py中编写;

    app/__init__.py;

    #!/usr/bin/python3
    # -*- coding:utf-8 -*-
    # Project: MicroFilm 
    # Software: PyCharm
    # Time    : 2018-09-28 16:36
    # File    : __init__.py.py
    # Author  : 天晴天朗
    # Email   : tqtl@tqtl.org
    
    from flask import Flask, render_template
    
    app = Flask(__name__)
    
    app.debug = True
    
    from app.home import home as home_blueprint
    from app.admin import admin as admin_blueprint
    
    app.register_blueprint(home_blueprint)
    app.register_blueprint(admin_blueprint, url_prefix="/admin")
    
    
    @app.errorhandler(404)
    def page_not_found(error):
        return render_template("home/404.html"), 404 

    5-1 管理员登录-后台布局搭建

    5.1.1 后台布局搭建;

    5.1.2 管理员的登录和退出;

    #!/usr/bin/python3
    # -*- coding:utf-8 -*-
    # Project: MicroFilm 
    # Software: PyCharm
    # Time    : 2018-09-28 16:38
    # File    : views.py
    # Author  : 天晴天朗
    # Email   : tqtl@tqtl.org
    
    from . import admin
    from flask import render_template, redirect, url_for
    
    
    @admin.route("/")
    def index():
        return "<h1 style='color:blue'>This is admin site!<h1>"
    
    
    @admin.route("/login/")
    def login():
        return render_template("admin/login.html")
    
    
    @admin.route("/logout/")
    def logout():
        return redirect(url_for("admin.login"))

    5.1.3 后台布局搭建;

    5.1.4 include引用报错处理;

    5.1.5 修改密码;

    5-2 修改密码-控制面板-标签管理页面搭建

    5.2.1 修改密码;

    5.2.2 控制面板;

    5.2.3 调整页面,显示内存仪表盘;

    5.2.4 标签管理页面搭建;

     

    5-3 电影管理-上映预告管理页面搭建

    5.3.1 编辑电影和电影列表;

     

    5.3.2 编辑上映预告和上映电影列表;

    5-4 会员-收藏-评论管理页面搭建

    5.4.1  会员列表;

    5.4.2 评论管理页面搭建;

    5-5 收藏-日志-角色管理页面搭建

    5.5.1 收藏管理列表搭建;

    5.5.2 操作日志列表;

    5.5.3 角色管理列表搭建;

    5.5.4 添加权限和权限列表;

    5-6 管理员页面搭建

    5.6.1 管理员页面搭建;

    6-1 管理员登录

    6.1.1 调整项目代码结构;

    6.1.2 flask-wtf第三方模块的安装;

    6.1.3 编写LoginForm类以及报错处理;

     

     

     

    6-2 标签管理

    6.2.1 标签管理;

    6-3 电影管理-添加电影

    6.3.1 电影管理;

    6-4 电影管理-列表、删除、编辑

    6.4.1 电影列表;

     

    6-5 预告管理

    6-6 会员管理

    6-7 评论-收藏管理

    6-8 修改密码

    6-9 日志管理

    7-1 权限管理

    7-2 角色管理

    7-3 管理员管理

    7-4 访问权限控制

    8-1 会员注册

    8-2 会员登录

    8-3 修改会员资料

    8-4 修改密码

    8-5 会员登录日志

    9-1 上映预告-标签筛选-电影分页

    9-2 电影搜索-电影详情

    10-1 电影评论-统计

    10-2 收藏电影

    10-3 电影弹幕-代码优化及Bug处理

    11-1 CentOS安装LNMP

    11.1.1 LNMP即——Linux + Nginx + MySQL+Python;

    • 安装Python解释器的依赖包 yum install openssl-devel bzip2-devel expat-deval gdbm-devel realine-devel gcc gcc-c++
    • 解压缩Python-3.6.1.tgz
    • yum install mariadb;systemctl start mariadb.service;
    • 修改mariadb的字符集为utf8,my.cnf文件;
    • yum install nginx;# 推荐使用yum安装
    • yum install gcc gcc-c++ opensll-devel pere-devel httpd-tools;
    • useradd nginx
    • ./configure --prefix==/usr/local/nginx --user==nginx --group=nginx --with http_ssl_module --with-http_mp4_module --with-http_flv_module     make&make install 
    • ln -s /usr/local/nginx /usr/sbin/
    • nginx 
    • netstat -lntup|grep nginx

    11-2 部署电影网站-流媒体访问限制

    11.2.1 部署微电影网站;

    • pip3 install -i https://pypi.douban.com/simple --trusted-host pypi.douban.com  -r requirements.txt;
    • scp -r movie_project root@192.168.0.1:/root/# 程序包;
    • 数据库中导入初始化数据;source /root/movie.sql;
    • cp -a  movie_project /usr/local/html/下;
    • nohup python manage.py runserver -h 127.0.0.1 -p 5000,开启四个进程;

     

     

     

    11.2.2 流媒体的访问限制;

    • 限制单个IP能发起的连接数:limit_conn addr:1;
    • 限制视频速率:limit_rate 1024K;
    • 修改配置后,一定记得重启nginx,重启之前进行语法检查!!!nginx -t ;  sytemctl reload nginx;

    nginx.conf; 

    worker_processes 4;
    events {
        worker_connections 262140;
    }
    http {
        include mime.types;
        default_type application/octet-stream;
        sendfile on;
        keepalive_timeout 65;
        limit_conn_zone $binary_remote_addr zone=addr:5m;
        upstream movie {
            server 127.0.0.1:5001;
            server 127.0.0.1:5002;
            server 127.0.0.1:5003;
            server 127.0.0.1:5004;
        }
        server {
            listen 80;
            server_name localhost;
            location / {
                root html;
                index index.html index.htm;
                proxy_pass http://movie;
            }
            location ~ \.flv$ {
                flv;
                limit_conn addr 4;
                limit_rate 1024k;
                rewrite ^/static/uploads/(.+?).flv$ /movie_project/app/static/uploads/$1.flv permanent;
            }
            location ~ \.mp4$ {
                mp4;
                limit_conn addr 4;
                limit_rate 1024k;
                rewrite ^/static/uploads/(.+?).mp4$ /movie_project/app/static/uploads/$1.mp4 permanent;
            }
            error_page 500 502 503 504 /50x.html;
            location = /50x.html {
                root html;
            }
        }
    }

     

     

     

     

     

     

    转载于:https://www.cnblogs.com/tqtl911/p/9718346.html

    展开全文
  • 语言解释器:使用Scala和Python构建的“微型语言解释器”
  • 基于Spring Cloud和Netflix OSS 构建微服务
  • 使用Flask构建的微服务的骨架
  • 使用Tendermint构建区块链应用程序的Python微框架 受到Flask的启发,py-tendermint使得快速创建Tendermint ABCI应用程序的原型变得容易。 注意:由于ABCI更改,当前版本已损坏。有关此过渡,请参阅py-abci py-...
  • M(ock)Object 是一个用于构建对象和对象树以进行模拟和存根的小型库。 它并不是作为模拟框架的替代品,而是作为一种补充。 基础知识,动态对象规范 创建一个新对象很容易。 >> > from mobject import MObject >> ...
  • 您正在使用Django构建具有微服务架构的应用程序。 您具有通过HTTP与每个服务器通信的服务器服务,每个服务都是它自己的Django项目。 您需要为每个服务运行./manage.py runserver [port]来启动它,并在开发时具有应用...
  • 构建完成之后,demo-0.0.1.jar就生成在/target目录下了,执行以下命令: java -jar target/demo-0.0.1.jar 启动完成后,通过curl命令访问服务或者浏览器访问: curl http://localhost:8080 结束语 一个简单的Spring ...

    前言

    Spring Boot是一个独立的、工业级的( production-grade) 基于Spring框架的应用。Spring Boot非常开放,在Spring Paltform的基础上集成了很多第三方类库,使得Spring Boot开发非常简单,开箱即用,只需要简单的配置,就可以把应用跑起来。实际上,java的发展是比较缓慢的,也比较臃肿,如果你想搭建一个java ee的简单例子,不依赖于任何框架,实际上,就算依赖其他框架,搭建的步骤和配置都非常繁琐,感谢Pivotal,提供了如此便利、稳定的框架。

    Python之Helloworld

    让我们来看看Python搭建一个Web的Helloworld,就知道有多简单了。

    • 安装python,我的版本是3.6
    • 开发工具,PyCharm


    好了,打开PyCharm,创建一个Python项目,这里略过。

    想看看项目骨架,项目命名为WebFlash


    /templates/hello.html

    <!doctype html>
    <title>Hello from Flask</title>
    {% if name %}
      <h1>Hello {{ name }}!</h1>
    {% else %}
      <h1>Hello, World!</h1>
    {% endif %}

    __init__.py

    from flask import render_template
    from flask import Flask
    app = Flask(__name__)
    
    
    @app.route('/hello/')
    @app.route('/hello/<name>')
    def hello(name=None):
        return render_template('hello.html', name=name)
    
    
    if __name__ == '__main__':
        app.run()

    在PyCharm里面启动项目


    能看到应用已经跑起来了,通过浏览器访问页面http://127.0.0.1:5000/hello


    Nice,一个Python的hello world就跑起来了。

    Spring Boot之HelloWorld

    搭建Spring Boot需要依赖JDK和Maven,当然也可以用Gradle,这里我用了Maven,开发工具是STS。

    • JDK 1.8.0_40
    • Maven 3.5
    • IDE STS
    • Spring Boot 1.5.10.RELEASE,目前最新版本是2.1.0

    用STS创建一个Spring Boot项目,也可以通过curl的方式下载项目骨架,这里略过。


    SpringRestdocsApplication.java如下:

    package com.chen.demo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class SpringRestdocsApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(SpringRestdocsApplication.class, args);
    	}
    }

    HomeController.java如下:

    package com.chen.demo;
    
    import java.util.Collections;
    import java.util.Map;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HomeController {
    
    	@GetMapping("/")
    	public Map<String, Object> greeting() {
    		return Collections.singletonMap("message", "Hello World");
    	}
    }

    pom.xml如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    
    	<groupId>com.chen</groupId>
    	<artifactId>demo</artifactId>
    	<version>0.0.1</version>
    	<packaging>jar</packaging>
    
    	<name>spring-restdocs</name>
    	<description>Spring API RestDocs for Spring Boot</description>
    
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>1.5.10.RELEASE</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    		<java.version>1.8</java.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    		</dependency>
    		
    		<dependency>
                <groupId>org.springframework.restdocs</groupId>
                <artifactId>spring-restdocs-mockmvc</artifactId>
                <scope>test</scope>
            </dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    			<plugin>
        <groupId>org.asciidoctor</groupId>
        <artifactId>asciidoctor-maven-plugin</artifactId>
        <executions>
            <execution>
                <id>generate-docs</id>
                <phase>prepare-package</phase>
                <goals>
                    <goal>process-asciidoc</goal>
                </goals>
                <configuration>
                    <sourceDocumentName>index.adoc</sourceDocumentName>
                    <backend>html</backend>
                    <attributes>
                        <snippets>${project.build.directory}/snippets</snippets>
                    </attributes>
                </configuration>
            </execution>
        </executions>
    </plugin>
    		</plugins>
    	</build>
    
    
    </project>

    到项目的工程目录下,执行

    mvn clean package

    构建完成之后,demo-0.0.1.jar就生成在/target目录下了,执行以下命令:

    java -jar target/demo-0.0.1.jar

    启动完成后,通过curl命令访问服务或者浏览器访问:

    curl http://localhost:8080


    结束语

    一个简单的Spring Boot微服务就完成了,非常的简单,我们甚至都没看到Tomcat、Jetty,它们是怎么去加载的呢?恩,刨根问底,下篇继续。


    展开全文
  • 使用Golang和MongoDB构建微服务 根据 的 Python版本的微服务改造成 Golang版本 一共有4个微服务 Movie Service: 是关于电影的基本信息,标题、评分等 ShowTimes Service: 关于电影上映时间的信息 Booking Service: ...
  • 使用python做web开发面临的一个最大的问题就是性能,在解决C10K问题上显的有点吃力。有些异步框架Tornado、Twisted、Gevent 等就是为了解决性能问题。这些框架在性能上有些提升,但是也出现了各种古怪的问题难以解决...
  • 压缩包下载后先解压到项目的目录,安装好flask需要的插件,根据表配置好MySQL数据库即可运行。
  • flask:用于构建Web应用程序的Python微型框架
  • docker构建python微服务

    千次阅读 2018-11-17 12:54:58
    1.拉取python镜像  docker pull python:3.6 2.运行python镜像并进入容器中 docker run -it --entrypoint bash python:3.6 ...4.为容器安装thrift, 因为使用python构建微服务需要thrift  pip insta...

    1.拉取python镜像

     docker pull python:3.6

    2.运行python镜像并进入容器中

    docker run -it --entrypoint bash python:3.6

    3.检测环境

    在容器中输入python,显示python版本代表容器正常

     

    4.为容器安装thrift, 因为使用python构建微服务需要thrift

         pip install thrift

    5.创建新的镜像(同时包含python和thrift)

    cd /usr/local/microservice/message-thrift-python-service/

    创建新的镜像命令,同时包含python和thrift : docker build -t python-base:latest -f Dockerfile.base .

    这里的Dockerfile.base内容:

    FROM python:3.6
    MAINTAINER xxx xxx@imooc.com
    
    RUN pip install thrift

    6.利用新的镜像来将python项目构建成第三个镜像(python环境+thrift+python项目)

       docker build -t message-service:latest .

    注意这里会默认指定当前路径下的DockerFile文件进行运行,内容如下:

    FROM python-base:latest
    MAINTAINER xxx xxx@imooc.com
    
    ENV PYTHONPATH /
    COPY message /message
    
    ENTRYPOINT ["python", "/message/message_service.py"]

    7.运行镜像,构建容器

    docker run  -it message-service

    当显示下面内容时代表容器运行成功

    8.检验容器是否运行成功:

    再打开一个终端,输入:docker ps -a ,当显示容器up则代表运行成功

     

    如果过程中出现需要修改Dockerfile或者项目模块文件变动,那么重新输入各种拉取和构建镜像的命令会很麻烦,这里比较好的方案就是使用脚本,将反复使用的命令写入脚本,下次重新构建只要执行脚本就行了

    在这里我创建了俩个脚本文件:

    build_base.sh

    #!/usr/bin/env bash
    
    docker build -t python-base:latest -f Dockerfile.base .

    build_sh

    #!/usr/bin/env bash
    docker build -t message-service:latest .
    docker push message-service:latest

    分别是用来运行dockerfile.base和dockerfile文件

    在linux中运行sh文件命令:  sh + ./文件名

    目录结构如下:

    展开全文
  • 从零开始用 Python 构建神经网络

    千次阅读 2018-09-08 12:39:14
    雷锋网 AI 研习社按:本文为雷锋网字幕组编译的技术博客,原文章标题为:How to build your own Neural Network from scratch in Python,作者 James Loy 原文链接:...
  • Merlin 是一个用 Python 编写的微型引擎,用于构建 RPG 游戏。 这是为了好玩,旨在学习、搜索和提高我关于创建自己的 RPG 引擎的知识,希望您喜欢并帮助我改进它。 目标是继续使用纯 Python 以在任何地方使用,任...
  • Ambassador:基于Envoy Proxy构建用于微服务的开源Kubernetes原生API网关
  • 2017/3/12 28.1 distutils 构建和安装Python模块 Python 3.6.1rc1文档 28.1distutils建筑和安装Python模块 该distutils包提供了对在Python安装中构建和安装附加模块的支持新的模块可以是100的 Python 或者可以是用C...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,352
精华内容 9,340
关键字:

python构建微服务

python 订阅