「Django框架」-视图函数FBV(flask 视图函数)
ccwgpt 2024-10-28 15:00 25 浏览 0 评论
函数视图
一个视图函数,简称视图,是一个简单的Python函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个 404 错误,一个 XML 文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。
应用程序目录中的名为views.py的文件中。
前面我们学习中视图都是通过定义函数来实现的,例如:
# views.py
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
username = request.POST.get('username')
pwd = request.POST.get('pwd')
if username and pwd:
res['user'] = username
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
res['msg'] = '用户名或密码错误'
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
# *************************
# urls.py
from .views import login
urlpatterns = [
path('login/', login, name='login')
]
http请求中产生两个核心对象:
1)HTTP 请求--->HttpRequest 对象,用户请求相关的所有信息(对象);
HTTP 协议以【请求 - 回复 】的方式工作。客户发送请求时,可以在请求中附加数据。服务器通过解析请求,就可以获得客户传来的数据,并根据 URL 来提供特定的服务。
一个请求的大概流程:
HTTP请求流程
通过 TCP 三次握手进行连接,然后开始传数据,客户端发送请求给服务器,服务器作出相应的相应返回给客户端。
2)HTTP 响应--->HttpResponse 对象,响应字符串。
如:
# views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("你好")
# 在urls.py中修改配置
from . import views
path('', views1.index, name='index'),
上面我们用到的request,就是HttpRequest对象。HttpResponse("你好"),就是HttpResponse对象,它向http请求响应了一段字符串。
视图函数,就是围绕着HttpRequest和HttpResponse这两个对象进行的。
HttpRequest 对象
Django在接收到http请求之后,Django会将http协议请求报文中的请求行、首部信息、内容主体封装到一个HttpRequest对象,并且将HttpRequest对象当作参数传给视图函数的第一个参数request。在视图函数中,通过访问该对象的属性便可以提取http请求数据。
常用属性
HttpRequest对象上大部分的属性都是只读的。因为这些属性是从客户端上传上来的,没必要做任何的修改。以下将对一些常用的属性进行讲解:
request.scheme:网络请求的协议,一般是http和https。
request.path:当前请求 URL 路径,但不包含协议和域名以及参数。比如https://www.qmpython.com/articles/detail-45.html,那么 path就是/articles/detail-45.html。
request.method:代表当前请求的http方法。一般是GET还是POST。
request.GET:一个类似于字典的django.http.request.QueryDict对象,可以通过访问字典的方式访问里面的值,里面的值是通过GET请求传递进来的参数(以?xxx=xxx的方式)。
# 当请求url为:http://www.qmpython.com:8004/user/index/3.html?a=1&b=2
print(request.GET) # 输出:<QueryDict: {'a': ['1'], 'b': ['2']}>
print(request.GET.get('a')) # 输出:1
print(request.GET.get('b')) # 输出:2
# 针对像这种,http://www.qmpython.com:8004/user/index/3.html?a=1&b=2&c=3&c=4&c=5,存在同个参数多个值的情况
print(request.GET) # <QueryDict: {'a': ['1'], 'b': ['2'], 'c': ['3', '4', '5']}>
print(request.GET.get('a')) # 1
print(request.GET.get('b')) # 2
print(request.GET.getlist('c')) # ['3', '4', '5']
request.POST:一个类似于字典的django.http.request.QueryDict对象,封装了POST请求所包含的表单数据。注意,这个POST里面不包含上传的文件信息。
例如模板文件login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
</head>
<body>
<h2>注册界面</h2>
<form action="" method="post">
{% csrf_token %} <!-- 必须加上这一行,后续会详细介绍 -->
用户名:<input type="text" name="username" placeholder="请输入账号"/><br/>
密 码:<input type="password" name="password"/><br/>
爱好:
<input type="checkbox" name="hobbies" value="music">音乐
<input type="checkbox" name="hobbies" value="read">阅读
<input type="checkbox" name="hobbies" value="dancing">跳舞
<br/>
<input type="submit" value="注册"/>
</form>
</body>
</html>
视图函数views.py:
def index(request, id):
if request.method == 'GET':
print(request.GET) # <QueryDict: {'a': ['1'], 'b': ['2'], 'c': ['3', '4', '5']}>
print(request.GET.get('a')) # 1
print(request.GET.get('b')) # 2
print(request.GET.getlist('c')) # ['3', '4', '5']
return render(request, 'user/index.html')
elif request.method == 'POST':
print(request.POST)
# <QueryDict: {'csrfmiddlewaretoken': ['J390sN2dzBcW5lCg37ywxhrIVi3MXepLy1Qal7tYA8zYhVH9TJAdMfEV0SCgXqcM'],
# 'username': ['qmpython'], 'password': ['1234'], 'hobbies': ['music', 'dancing']}>
print(request.POST.get('username')) # qmpython
print(request.POST.get('password')) # 1234
print(request.POST.getlist('hobbies')) # ['music', 'dancing']
return HttpResponse('注册信息提交成功')
request.body:http请求中传递的原始数据,是一个byte类型的string。
当浏览器基于http协议的POST方法提交数据时,数据会被放到请求体中发送给Django,Django会将接收到的请求体数据存放于HttpRequest.body属性中,因为该属性的值为Bytes类型,所以通常情况下直接处理Bytes并从中提取有用数据的操作是复杂而繁琐的,好在Django会对它做进一步的处理与封装以便我们更为方便地提取数据,比如对于form表单来说,提交数据的常用方法为GET与POST。
1)如果表单属性method='GET',那么在提交表单时,表单内数据不会存放于请求体body中,而是会将表单数据按照k1=v1&k2=v2&k3=v3的格式放到url中,然后发送给Django,Django会将这些数据封装到request.GET中,注意此时的request.body为空,无用!模板文件中:
<!-- 如将之前的表单提交改成get方法 -->
<form action="" method="get">
...
</form>
<!--
输入地址:http://www.qmpython.com:8004/user/index/3.html?a=1&b=6
填写完用户名和密码,提交之后,表单数据按照k1=v1&k2=v2形式放到url后:
http://www.qmpython.com:8004/user/index/3.html?csrfmiddlewaretoken=ZpICWaQOnRqYfgQGbkgELZYyt6S4hajzSnEqYhv0qomjTmOChQFG4LMeXNDd54i0&username=qmpython&password=123456&hobbies=read&hobbies=dancing
原来的参数a,b被覆盖了!
-->
视图views.py中:
print(request.body) # b'' # get方式请求,请求数据不会放到body中
print(request.GET)
# <QueryDict: {'csrfmiddlewaretoken': ['ZpICWaQOnRqYfgQGbkgELZYyt6S4hajzSnEqYhv0qomjTmOChQFG4LMeXNDd54i0'], 'username': ['qmpython'], 'password': ['123456'], 'hobbies': ['read', 'dancing']}>
2)如果表单属性method='POST',那么在提交表单时,表单内的所有数据都会存放于请求体中,在发送给Django后会封装到request.body里,此时Django为了方便我们提取数据,会request.body的数据进行进一步的处理,具体如何处理呢,需要从form表单提交数据的编码格式说起:form表单对提交的表单数据有两种常用的编码格式,可以通过属性enctype进行设置,如下
- enctype="application/x-www-form-urlencoded"(默认的编码格式)。
- enctype="multipart/form-data"(使用form表单上传文件时只能用该编码)。
如果form表单提交数据是按照第一种方式,那么request.body中数据的格式类似于GET方法的数据格式,如k1=v1&k2=v2,此时Django会将request.body中的数据提取出来封装到request.POST中方便我们提取。
<!-- 如将之前的表单提交改成get方法 -->
<form action="" method="post">
...
</form>
视图中:
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
print(request.body) #b'csrfmiddlewaretoken=JbgAeQk8IMiCvn6uxBuM6mMix9l1U4Lpy9XK7aLTJjFEHXbnndwtlkZvCJUvUgyq&username=admin&password=123456'
print(request.POST) # <QueryDict: {'csrfmiddlewaretoken': ['JbgAeQk8IMiCvn6uxBuM6mMix9l1U4Lpy9XK7aLTJjFEHXbnndwtlkZvCJUvUgyq'], 'username': ['admin'], 'password': ['123456']}>
return HttpResponse('登录成功')
request.FILES:也是一个类似于字典的django.http.request.QueryDict对象。这个属性中包含了所有上传的文件。如果使用form表单POST上传文件的话,文件数据将包含在request.Files属性中。只有在请求的方法为POST 且提交的form表单带有enctype="multipart/form-data"的情况下才会包含数据,否则,FILES将为一个空的类似于字典的对象。
该属性值为一个类似于字典的对象,可以包含多组key:value(对应多个上传的文件),其中每个key为<input type="file" name="" />中name属性的值,而value则为对应的文件数据。
<form action="" method="post" enctype="multipart/form-data">
头像:<input type="file" name="head_img">
</form>
#views.py
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
#print(request.body)
print(request.POST) # <QueryDict: {'csrfmiddlewaretoken': ['yIpuMsAdApp1mPt9tqEHJxXUkLxmS7t3CebPbZhWz6TIaKoDJTMTHG9oBkugHxnt'], 'username': ['admin'], 'password': ['123456']}>
print(request.POST.get('username')) # admin
print(request.FILES) # <MultiValueDict: {'head_img': [<InMemoryUploadedFile: DSP_IP.jpg (image/jpeg)>]}>
print(request.FILES.get('head_img')) # DSP_IP.jpg
# 然后可以使用文件写入模块write
return HttpResponse('登录成功')
request.COOKIES:一个标准的Python字典,包含所有的cookie信息,键值对都是字符串类型。
request.session:返回一个QueryDict的类字典类型的集合,用来操作服务器的session,这个属性要有效,必须添加SessionMiddleware这个中间件。
MIDDLEWARE = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
...
]
request.user:user 只有当Django启用 AuthenticationMiddleware 中间件时才可用。它的值是一个 setting.py 里面AUTH_USER_MODEL 字段所定义的类的对象,表示当前登录的用户。如果用户当前没有登录,user 将设为 django.contrib.auth.models.AnonymousUser 的一个实例。可以通过 is_authenticated() 区分它们。
MIDDLEWARE = [
...
'django.contrib.auth.middleware.AuthenticationMiddleware',
...
]
request.META:一个标准的 Python 字典,包含所有的 HTTP 首部,具体的头部信息取决于客户端和服务器。
CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。CONTENT_TYPE —— 请求的正文的MIME 类型。HTTP_ACCEPT —— 响应可接收的Content-Type。HTTP_ACCEPT_ENCODING —— 响应可接收的编码。HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。HTTP_HOST —— 客服端发送的HTTP Host 头部。HTTP_REFERER —— Referring 页面。HTTP_USER_AGENT —— 客户端的user-agent 字符串。QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。REMOTE_ADDR —— 客户端的IP 地址。REMOTE_HOST —— 客户端的主机名。REMOTE_USER —— 服务器认证后的用户。REQUEST_METHOD —— 一个字符串,例如”GET“ 或”POST“。SERVER_NAME —— 服务器的主机名。SERVER_PORT —— 服务器的端口(是一个字符串)。
上面,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时,都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_ 前缀。
所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。
超实用例子:
如果服务器使用了nginx做反向代理或者负载均衡,那么这个值返回的是127.0.0.1 ,这时候可以使用HTTP_X_FORWARDED_FOR来获取,所以获取 ip 地址的代码片段如下:
#获取IP
if 'HTTP_X_FORWARDED_FOR' in request.META:
ip = request.META['HTTP_X_FORWARDED_FOR']
else:
ip = request.META['REMOTE_ADDR']
常用方法
request.is_secure():是否是采用https协议。
request.is_ajax():是否采用ajax发送的请求。原理就是判断请求头中是否存在X-Requested-With:XMLHttpRequest。
request.get_host():服务器的域名。如果在访问的时候还有端口号,那么会加上端口号。比如www.qmpython.com:9000。
request.get_full_path():获取url地址的完整path。如果有查询字符串,还会加上查询字符串。比如/music/bands/?print=True。
request.get_raw_uri():获取请求的完整url。
# 如果请求地址是:http://www.qmpython.com:8004/user/index/3.html?a=1&b=6
print(request.path) # /user/index/3.html
print(request.get_full_path()) # /user/index/3.html?a=1&b=6
print(request.get_raw_uri()) # http://www.qmpython.com:8004/user/index/3.html?a=1&b=6
HttpResponse 对象
Django服务器接收到客户端发送过来的请求后,会将提交上来的这些数据封装成一个HttpRequest对象传给视图函数。那么视图函数在处理完相关的逻辑后,也需要返回一个响应给浏览器。而这个响应,我们必须返回HttpResponseBase或者他的子类的对象。相应对象主要有三种形式:HttpResponse,render,redirect。而HttpResponse则是HttpResponseBase用得最多的子类。那么接下来就来介绍一下HttpResponse及其子类。
常用属性
content:代表要发送给客户端的内容。
status_code:返回的 HTTP 响应状态码。
content_type:返回的数据的 MIME 类型,返回的数据的 MIME 类型,默认为text/html;charset=utf-8。浏览器会根据这个属性,来显示数据。如果是text/html,那么就会解析这个字符串,如果text/plain,那么就会显示一个纯文本。常用的Content-Type如下:
- text/html(默认的,html 文件)
- text/plain(纯文本)
- text/css(css 文件)
- text/javascript(js 文件)
- multipart/form-data(文件提交)
- application/json(json 传输)
- application/xml(xml 文件)
设置请求头:response['X-Access-Token'] = 'xxxx'。
charset:响应体的编码,如果没有指定,则会使用content_type中设置的charset。
常用方法
render:将指定页面渲染后返回给浏览器。
render(request, template_name[, context])
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的HttpResponse对象。
def index(request):
articles = Article.objects.all().order_by('-id')
print(request.body)
context = {
'articles':articles,
}
return render(request, 'index.html',context)
参数:request:用于生成响应的请求对象。template_name:要使用的模板的完整名称,可选的参数context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。content_type:生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。status:响应的状态码。默认为 200。
render方法主要是将从服务器提取的数据,填充到模板中,然后将渲染后的 html静态文件返回给浏览器。这里一定要注意:render渲染的是模板。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>博客首页</title>
</head>
<body>
<div style="margin: 0 auto">
<ul>
<h3>最新文章</h3>
{% for article in articles %}
<li>{{ x.article }}</li>
{% endfor %}
</ul>
</div>
</body>
</html>
上面 {}之间包括的就是我们要从数据库取出的数据,进行填充。对于这样一个没有填充数据的html文件,浏览器是不能进行渲染的,所以,对于上述{}之间的内容先要被render进行渲染之后,才能发送给浏览器。
redirect:多用于页面跳转。
redirect的参数可以是:一个模型:将调用模型的get_absolute_url() 函数。
from django.shortcuts import redirect
def my_view(request):
...
# 传递一个对象,将调用get_absolute_url() 方法来获取重定向的URL
object = MyModel.objects.get(...)
return redirect(object)
一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称。
def my_view(request):
...
return redirect('some-view-name', foo='bar')
一个绝对的或相对的URL,将原封不动的作为重定向的位置。
def my_view(request):
...
return redirect('/some/url/')
# return redirect('https://www.django.cn/')
默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。
重定向分为永久性重定向和暂时性重定向,在页面上体现的操作就是浏览器会从一个页面自动跳转到另外一个页面。比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应该给他重定向到登录页面。
- 永久性重定向:http的状态码是301,多用于旧网址被废弃了要转到一个新的网址确保用户的访问,最经典的就是京东网站,你输入www.jingdong.com的时候,会被重定向到www.jd.com,因为jingdong.com这个网址已经被废弃了,被改成jd.com,所以这种情况下应该用永久重定向。
- 暂时性重定向:http的状态码是302,表示页面的暂时性跳转。比如访问一个需要权限的网址,如果当前用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。
在Django中,重定向是使用redirect(to, *args, permanent=False, **kwargs)来实现的。to是一个url,permanent代表的是这个重定向是否是一个永久的重定向,默认是False。关于重定向的使用。请看以下例子:
from django.shortcuts import reverse,redirect
def profile(request):
if request.GET.get("username"):
return HttpResponse("%s,欢迎来到个人中心页面!")
else:
return redirect(reverse("user:login"))
render和redirect两者区别: 第一,假如render返回一个登陆成功后的页面,刷新该页面将回复到跳转前页面。而 redirect 则不会 第二,如果页面需要模板语言渲染,需要的将数据库的数据加载到html,那么render方法则不会显示这一部分,render返回一个登陆成功页面,不会经过url路由分发系统,也就是说,不会执行跳转后url的视图函数。这样,返回的页面渲染不成功;而redirect是跳转到指定页面,当登陆成功后,会在url路由系统进行匹配,如果有存在的映射函数,就会执行对应的映射函数。
set_cookie:用来设置cookie信息。后面讲到授权的时候会着重讲到。
delete_cookie:用来删除cookie信息。
write:HttpResponse是一个类似于文件的对象,可以用来写入数据到数据体(content)中。
Django 限制请求 method
常用的请求 method
GET请求:一般用来向服务器获取数据,但不会向服务器提交数据,不会对服务器的状态进行更改。比如向服务器获取某篇文章的详情。
POST请求:一般是用来向服务器提交数据,会对服务器的状态进行更改。比如提交一篇文章给服务器。
限制请求装饰器
Django内置的视图装饰器可以给视图提供一些限制。比如这个视图只能通过GET的method访问等。以下将介绍一些常用的内置视图装饰器。
1)django.http.decorators.http.require_http_methods:这个装饰器需要传递一个允许访问的方法的列表。比如只能通过GET的方式访问。那么示例代码如下:
from django.views.decorators.http import require_http_methods
@require_http_methods(["GET"])
def my_view(request):
pass
2)django.views.decorators.http.require_GET:这个装饰器相当于是require_http_methods(['GET'])的简写形式,只允许使用GET的method来访问视图。示例代码如下:
from django.views.decorators.http import require_GET
@require_GET
def my_view(request):
pass
3)django.views.decorators.http.require_POST:这个装饰器相当于是require_http_methods(['POST'])的简写形式,只允许使用POST的method来访问视图。示例代码如下:
from django.views.decorators.http import require_POST
@require_POST
def my_view(request):
pass
4)django.views.decorators.http.require_safe:这个装饰器相当于是require_http_methods(['GET','HEAD'])的简写形式,只允许使用相对安全的方式来访问视图。因为GET和HEAD不会对服务器产生增删改的行为。因此是一种相对安全的请求方式。示例代码如下:
from django.views.decorators.http import require_safe
@require_safe
def my_view(request):
pass
公众号: Python野路子
野路子学习整理和分享Python入门和Python Web开发以及Python爬虫相关知识。欢迎互相学习交流,共同进步~~
相关推荐
- 定时任务工具,《此刻我要...》软件体验
-
之前果核给大家介绍过一款小众但实用的软件——小说规则下载器,可以把网页里的小说章节按照规则下载到本地,非常适合喜欢阅读小说的朋友。有意思的是,软件作者当时看到果核写的体验内容后,给反推荐到他的帖子里去...
- 前端定时任务的神库:Node-cron,让你的项目更高效!
-
在前端开发中,定时任务是一个常见的需求。无论是定时刷新数据、轮询接口,还是发送提醒,都需要一个可靠且灵活的定时任务解决方案。今天,我要向大家介绍一个强大的工具——Node-cron,它不仅能解决定时任...
- Shutter Pro!一款多功能定时执行任务工具
-
这是一款可以在电脑上定时执行多种任务的小工具,使用它可以根据时间,电量等来设定一些定时任务,像定时打开程序、打开文件,定时关机重启,以及定时弹窗提醒等都可以轻松做到。这是个即开即用的小工具,无需安装,...
- 深度解析 Redis 缓存击穿及解决方案
-
在当今互联网大厂的后端开发体系中,Redis缓存占据着极为关键的地位。其凭借高性能、丰富的数据类型以及原子性操作等显著优势,助力众多高并发系统从容应对海量用户的访问冲击,已然成为后端开发从业者不可或...
- 从零搭建体育比分网站完整步骤(比较好的体育比分软件)
-
搭建一个体育比分网站是一个涉及前端、后端、数据源、部署和维护的完整项目。以下是从零开始搭建的详细流程:一、明确项目需求1.功能需求:实时比分展示(如足球、篮球、网球等)支持多个联赛和赛事历史数据查询比...
- 告别复杂命令行:GoCron 图形界面让定时任务触手可及
-
如果你是运维人员或者经常接触一些定时任务的配置,那么你一定希望有一款图形界面来帮助你方便的轻松配置定时任务,而GoCron就是这样一款软件,让你的配置可视化。什么是GoCron从名字你就可以大概猜到,...
- Java任务管理框架核心技术解析与分布式高并发实战指南
-
在当今数字化时代,Java任务管理框架在众多应用场景中发挥着关键作用。随着业务规模的不断扩大,面对分布式高并发的复杂环境,掌握其核心技术并进行实战显得尤为重要。Java任务管理框架的核心技术涵盖多个方...
- 链表和结构体实现:MCU软件定时器(链表在单片机中的应用)
-
在一般的嵌入式产品设计中,介于成本、功耗等,所选型的MCU基本都是资源受限的,而里面的定时器的数量更是有限。在我们软件设计中往往有多种定时需求,例如脉冲输出、按键检测、LCD切屏延时等等,我们不可能...
- SpringBoot定时任务(springboot定时任务每小时执行一次)
-
前言在我们开发中,经常碰到在某个时间点去执行某些操作,而我们不能人为的干预执行,这个时候就需要我们使用定时任务去完成该任务,下面我们来介绍下载springBoot中定时任务实现的方式。定时任务实现方式...
- 定时任务新玩法!systemd timer 完整实战详解
-
原文链接:「链接」Hello,大家好啊!今天给大家带来一篇使用systemdtimer实现定时任务调度的详细实战文章。相比传统的crontab,systemdtimer更加现代化、结构清晰...
- Celery与Django:打造高效DevOps的定时任务与异步处理神器
-
本文详细介绍了Celery这一强大的异步任务队列系统,以及如何在Django框架中应用它来实现定时任务和异步处理,从而提高运维开发(DevOps)的效率和应用性能。下面我们先认识一下Cele...
- 订单超时自动取消的7种方案,我用这种!
-
前言在电商、外卖、票务等系统中,订单超时未支付自动取消是一个常见的需求。这个功能乍一看很简单,甚至很多初学者会觉得:"不就是加个定时器么?"但真到了实际工作中,细节的复杂程度往往会超...
- 裸机下多任务框架设计与实现(gd32裸机配置lwip 网络ping不通)
-
在嵌入式系统中,特别是在没有操作系统支持的裸机环境下,实现多任务执行是一个常见的挑战。本文将详细介绍一种基于定时器的多任务框架设计,通过全局时钟和状态机机制,实现任务的非阻塞调度,确保任务执行中不会出...
- 亿级高性能通知系统构建,小白也能拿来即用
-
作者介绍赵培龙,采货侠JAVA开发工程师分享概要一、服务划分二、系统设计1、首次消息发送2、重试消息发送三、稳定性的保障1、流量突增2、问题服务的资源隔离3、第三方服务的保护4、中间件的容错5、完善...
- 运维实战:深度拆解Systemd定时任务原理,90%的人不知道的玩法
-
运维实战:深度拆解Systemd定时任务原理,90%的人不知道的高效玩法一、Systemd定时任务的核心原理Systemd定时任务是Linux系统中替代传统cron的现代化解决方案,通过...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- MVC框架 (46)
- spring框架 (46)
- 框架图 (58)
- bootstrap框架 (43)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- laravel框架 (46)
- express框架 (43)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- grpc框架 (55)
- ppt框架 (48)
- 内联框架 (52)
- winform框架 (46)
- gui框架 (44)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)