要实现开发是不是也要具备阿里云是如何实现的之类的

没有更多推荐了,
不良信息举报
举报内容:
android开发之用阿里云OSS加载图片
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长![云主机]使用阿里云服务器进行开发的小结
有回复时邮件通知我
<span class="tipso_style" id="tip-w-j" data-tipso=''>
文章总数:1076 篇
留言数量:6324 条
标签总数:1780 个
运行时间:1465 天
浏览总量:1550655 次
最后更新:日
页面查询:本次查询66 次
页面运行:本次运行0.239 秒
记住我的登录信息
点击“立即注册”转到用户注册页面。
输入用户名或电子邮箱地址,您会收到一封新密码链接的电子邮件。
用户名或电子邮件地址浅谈django开发者模式中的autoreload是如何实现的_python
作者:用户
在开发django应用的过程中,使用开发者模式启动服务是特别方便的一件事,只需要 python manage.py runserver 就可以运行服务,并且提供了非常人性化的autoreload机制,不需要手动重启程序就可以修改代码并看到反馈。刚接触的时候觉得这个功能比较人性化,也没觉得是什么特别高大上的技术。后来有空就想着如果是我来实现这个autoreload会怎么做,想了很久没想明白,总有些地...
在开发django应用的过程中,使用开发者模式启动服务是特别方便的一件事,只需要 python manage.py runserver 就可以运行服务,并且提供了非常人性化的autoreload机制,不需要手动重启程序就可以修改代码并看到反馈。刚接触的时候觉得这个功能比较人性化,也没觉得是什么特别高大上的技术。后来有空就想着如果是我来实现这个autoreload会怎么做,想了很久没想明白,总有些地方理不清楚,看来第一反应真是眼高手低了。于是就专门花了一些时间研究了django是怎样实现autoreload的,每一步都看源码说话,不允许有丝毫的想当然:
1、runserver命令。在进入正题之前其实有一大段废话,是关于runserver命令如何执行的,和主题关系不大,就简单带一下:
命令行键入 python manage.py runserver 后,django会去寻找runserver这个命令的执行模块,最后落在
django\contrib\staticfiles\management\commands\runserver.py模块上:
#django\contrib\staticfiles\management\commands\runserver.py
from django.core.management.commands.runserver import \
Command as RunserverCommand
class Command(RunserverCommand):
help = "Starts a lightweight Web server for development and also serves static files."
而这个Command的执行函数在这:
#django\core\management\commands\runserver.py
class Command(BaseCommand):
  def run(self, **options):
  Runs the server, using the autoreloader if needed
  use_reloader = options['use_reloader']
  if use_reloader:
    autoreload.main(self.inner_run, None, options)
    self.inner_run(None, **options)
这里有关于use_reloader的判断。如果我们在启动命令中没有加--noreload,程序就会走autoreload.main这个函数,如果加了,就会走self.inner_run,直接启动应用。
其实从autoreload.main的参数也可以看出,它应该是对self.inner_run做了一些封装,autoreload的机制就在这些封装当中,下面我们继续跟。
PS: 看源码的时候发现django的command模式还是实现的很漂亮的,值得学习。
2、autoreload模块。看autoreload.main():
#django\utils\autoreload.py:
def main(main_func, args=None, kwargs=None):
  if args is None:
    args = ()
  if kwargs is None:
    kwargs = {}
  if sys.platform.startswith('java'):
    reloader = jython_reloader
    reloader = python_reloader
  wrapped_main_func = check_errors(main_func)
  reloader(wrapped_main_func, args, kwargs)
这里针对jpython和其他python做了区别处理,先忽略jpython;check_errors就是把对main_func进行错误处理,也先忽略。看python_reloader:
#django\utils\autoreload.py:
def python_reloader(main_func, args, kwargs):
  if os.environ.get("RUN_MAIN") == "true":
    thread.start_new_thread(main_func, args, kwargs)
    try:
      reloader_thread()
    except KeyboardInterrupt:
      pass
    try:
      exit_code = restart_with_reloader()
      if exit_code & 0:
        os.kill(os.getpid(), -exit_code)
      else:
        sys.exit(exit_code)
    except KeyboardInterrupt:
      pass
第一次走到这里时候,环境变量中RUN_MAIN变量不是"true", 甚至都没有,所以走else, 看restart_with_reloader:
#django\utils\autoreload.py:
def restart_with_reloader():
while True:
  args = [sys.executable] + ['-W%s' % o for o in sys.warnoptions] + sys.argv
    if sys.platform == "win32":
      args = ['"%s"' % arg for arg in args]
    new_environ = os.environ.copy()
    new_environ["RUN_MAIN"] = 'true'
    exit_code = os.spawnve(os.P_WAIT, sys.executable, args, new_environ)
    if exit_code != 3:
      return exit_code
这里首先起一个while循环, 内部先把RUN_MAIN改成了"true",然后用os.spawnve方法开一个子进程(subprocess),看看os.spawnve的说明:
def spawnve(mode, file, args, env):
  """spawnve(mode, file, args, env) -& integer
  Execute file with arguments from args in a subprocess with the
  specified environment.
  If mode == P_NOWAIT return the pid of the process.
  If mode == P_WAIT return the process's exit code
  otherwise return -SIG, where SIG is the signal that killed it. """
  return _spawnvef(mode, file, args, env, execve)
其实就是再调一遍命令行,又走了一遍 python manage.py runserver。
接着看restart_with_reloader里的while循环,需要注意的是while循环退出的唯一条件是exit_code!=3。 如果子进程不退出,就一直停在 os.spawnve这一步; 如果子进程退出,而退出码不是3,while就被终结了;如果是3,继续循环,重新创建子进程。从这个逻辑可以猜想autoreload的机制:当前进程(主进程)其实啥也不干,就监视子进程的运行状况,子进程才是真正干事儿的;如果子进程以exit_code=3退出(应该由于检测到了文件修改),就再启动一遍子进程,新代码自然就生效了;如果子进程以exit_code!=3退出,主进程也结束,整个django程序就算跪了。这只是猜想,下面接着来验证。
3、子进程。上面其实有一个疑问,既然是重新启动了一次,为什么子进程不会接着生成子进程。原因就在于RUN_MAIN这个环境变量,主进程中把它改成了true,子进程走到python_reloader函数的时候:
#django\utils\autoreload.py:
def python_reloader(main_func, args, kwargs):
  if os.environ.get("RUN_MAIN") == "true":
    thread.start_new_thread(main_func, args, kwargs)
    try:
      reloader_thread()
    except KeyboardInterrupt:
      pass
    try:
      exit_code = restart_with_reloader()
      if exit_code & 0:
        os.kill(os.getpid(), -exit_code)
      else:
        sys.exit(exit_code)
    except KeyboardInterrupt:
      pass
if条件满足了,和主进程走了不一样的逻辑分支。在这里,首先去开一个线程,运行main_func,就是上文的 Command.inner_run。这里的thread模块是这么import的:
#django\utils\autoreload.py:
from django.utils.six.moves import _thread as thread
这里six模块的作用是兼容各种python版本:
[codeblock six]
#django\utils\six.py
class _SixMetaPathImporter(object):
A meta path importer to import six.moves and its submodules.
This class implements a PEP302 finder and loader. It should be compatible
with Python 2.5 and all existing versions of Python3
官网说明:
# https://pythonhosted.org/six/
Six: Python 2 and 3 Compatibility Library
Six provides simple utilities for wrapping over differences between Python 2 and Python 3. It is intended to support codebases that work on both Python 2 and 3 without modification. six consists of only one Python file, so it is painless to copy into a project.
所以如果程序想在python2和python3上都能跑,且鲁邦,six是重要的工具。之后抽个时间看下six,mark一下。
然后再开一个reloader_thread:
[codeblock autoreload_reloader_thread]
#django\utils\autoreload.py:
def reloader_thread():
  ensure_echo_on()
  if USE_INOTIFY:
    fn = inotify_code_changed
    fn = code_changed
  while RUN_RELOADER:
    change = fn()
    if change == FILE_MODIFIED:
      sys.exit(3) # force reload
    elif change == I18N_MODIFIED:
      reset_translations()
    time.sleep(1)
ensure_echo_on()其实还没看明白,貌似是针对类unix系统文件处理的,先略过;
USE_INOTIFY也是系统文件操作相关的变量,根据 inotify 是否可用选择检测文件变化的方法。
while循环,每隔1秒检测一下文件状态,如果是普通文件有变化,进程退出,退出码为3,主进程一看:退出码是3,就重启子进程。。。。这样就和上面连上了;如果不是普通文件变化,而是I18N_MODIFIED(.mo后缀的文件变化,二进制库文件之类的),那就 reset_translations ,大概意思是把已加载过的库缓存清理掉,下次重新加载。
以上就是autoreload机制的流程。其中还是有些细节不是特别清楚,比如不同操作系统文件变化的检测,但都是很细节的东西了,不涉及主流程。看完这些,我又问了自己一遍,如果是让我设计autoreload机制会怎样搞。现在我的答案是:直接把 django\utils\autoreload.py 文件拿来用啊。其实这是很独立的一个模块,而且特别通用,完全可以作为通用的autoreload解决方案,我还自己写个毛啊。
这篇浅谈django开发者模式中的autoreload是如何实现的就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
以上是互联网用户为您的的内容,在阿里云内部有更多的关于浅谈django开发者模式中的autoreload是如何实现的_python的内容,欢迎继续使用右上角搜索按钮进行搜索django、autoreload、以便于您获取更多的相关信息。
本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:zixun-group@service.aliyun.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。
若您要投稿,删除文章请联系邮箱:zixun-group@service.aliyun.com
工作人员会在5个工作日内回复
脚本栏目为您免费提供
相关信息,包括
的信息 ,所有
相关内容均不代表阿里云的意见!投稿、删除文章请联系邮箱:zixun-group@service.aliyun.com,工作人员5个工作日内回复。阿里云。本地开发的服务程序(需要使用数据库),如何放到云服务器上并使用云数据库_百度知道
阿里云。本地开发的服务程序(需要使用数据库),如何放到云服务器上并使用云数据库
我是菜鸟,在本地开发的服务程序(需要使用数据库),如何放到云服务器上并使用云数据库?我在开发本地的时候连接数据库是用本地的,完全本地开发。之后我想把服务程序放到阿里云上,并且用阿里云的数据库。我该怎么做阿里云数据库应该怎么创建
我有更好的答案
去购买RDS数据库,之后会给你一个内网的域名,在你的阿里云管理台中找到数据库并创建帐号,之后将以上信息配置进你程序的配置文件中就可以,和用本地的基本没区别,注意一点,ECS和RDS在同一个地域下,走内网访问。我有几张阿里云幸运券分享给你,用券购买或者升级阿里云相应产品会有特惠惊喜哦!把想要买的产品的幸运券都领走吧!快下手,马上就要抢光了。
采纳率:50%
为您推荐:
其他类似问题
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。【图文】阿里云公司战略及业务研究_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
阿里云公司战略及业务研究
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢

我要回帖

更多关于 阿里云slb实现 的文章

 

随机推荐