Python剑指offer-JZ8-跳台阶

Python剑指offer-JZ8-跳台阶

Python剑指offer-JZ8-跳台阶
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

题目分析
和斐波那契数列很像,结论就是f(n)=f(n-1)+f(n-2)(n>2),f(1)=1,f(2)=2.
这里可以从实际场景的角度去分析下这个结论:
假设我们现在正要踏上第n级台阶,因为我们每次只能跳1级或者2级,
那么意味着我们只有可能从第n-1或者第n-2级台阶上来迈出这一步.
即f(n)=f(n-1)+f(n-2).

Python代码(牛客网)
# -*- coding:utf-8 -*-
class Solution:
def jumpFloor(self, number):
# write code here
if number <1:
return 0
if number == 1:
return 1
if number == 2:
return 2
ret=0
a=1
b=2
for i in range(3,number+1):
ret=a+b
a=b
b=ret
return ret

python纯手动把一整段英文按句分割

python纯手动把一整段英文按句分割

因为我不知道 split() 这个函数,sad
花时间想的东西用个python函数直接就搞定,有点不甘心所以存一下(不得不感慨这些库函数都好厉害喔 python好厉害喔)
原本这段英文以字符串形式存储在变量 str 里
下面实现将这段话按句分割,每句话存储在一个字符串内,所有句话一起存进列表 s.
每句话都是完整的,有句号,无多余空格。
例:
str:

使用此代码输出s:

s = []
flag = 0 #标记一句话的结束
now = 0 #现在处理的位置

# 找到句号并标记,截取两句号之间的部分作为一句话
for i in str:
if i != ‘.’:
now += 1
continue
else:
# 从上一个句号的下一个字符,到本句号(含)
s.append(str[flag : now + 1])
now += 1
flag = now

# 去掉第2句话开始,每句话开头的空格
for j in range(len(s)):
if s[j][0] == ‘ ‘:
s[j] = s[j][1:]
else:
continue

Django文件下载方法总结

Django文件下载方法总结

方法一: 使用HttpResponse

import os
from django.http import HttpResponse

def media_file_download(request, file_path):
with open(file_path, ‘rb’) as f:
response = HttpResponse(f)
response[‘content_type’] = “application/octet-stream”
response[‘Content-Disposition’] = ‘attachment; filename={0}’.format(‘test.png’)
return response

# response也是一个类似文件的对象,有write等方法
with open(file_path, ‘rb’) as f:
response = HttpResponse()
response.write(f.read())
response[‘content_type’] = “application/octet-stream”
response[‘Content-Disposition’] = ‘attachment; filename={0}’.format(‘test.png’)
return response
缺点:其工作原理是先读取文件,载入内存,然后再输出。如果下载文件很大,该方法会占用很多内存。对于下载大文件,Django更推荐StreamingHttpResponse和FileResponse方法。

 

方法二: 使用SteamingHttpResponse

注意:Django is designed for short-lived requests. Streaming responses will tie a worker process for the entire duration of the response. This may result in poor performance.

Django是为短期请求而设计的。流式响应将在整个响应期间绑定工作进程。这可能导致性能不佳。

import os
from django.http import StreamingHttpResponse

def _file_iterator(file_obj, chunk_size=512):
file_obj.seek(0)
while True:
con = file_obj.read(chunk_size)
if con:
yield con
else:
break

def media_file_download(request, file_path):
with open(file_path, ‘rb’) as f:
response = StreamingHttpResponse(f)
response[‘content_type’] = “application/octet-stream”
response[‘Content-Disposition’] = ‘attachment; filename={0}’.format(‘test.png’)
return response

# StreamingHttpResponse还可以接受iterator作为参数
bio = BytesIO()
bio.writer(b’something’)
response = StreamingHttpResponse(_file_iterator(bio))
response[‘content_type’] = “application/octet-stream”
response[‘Content-Disposition’] = ‘attachment; filename={0}’.format(‘test.png’)
return response

方法三: 使用FileResponse

FileResponse是StreamingHttpResponse的子类,并且针对二进制文件做了优化。更推荐用这种方法来下载文件。

接受一个以‘rb’方法打开的文件,并且会自动关闭文件,所以无需使用with上下文管理器打开。

import os
from django.http import FileResponse

def media_file_download(request, file_path):
response = FileResponse(open(file_path, ‘rb’))
response[‘content_type’] = “application/octet-stream”
response[‘Content-Disposition’] = ‘attachment; filename={0}’.format(‘test.png’)
return response
 

 

 

Android Studio生成.so库与调用

新建androidstudio工程,如图:

%title插图%num
build.gradle :

apply plugin: ‘com.android.application’

android {
compileSdkVersion 26
defaultConfig {
applicationId “com.mediatek.camera.myapplication”
minSdkVersion 23
targetSdkVersion 26
versionCode 1
versionName “1.0”
testInstrumentationRunner “android.support.test.runner.AndroidJUnitRunner”
externalNativeBuild {
cmake {
cppFlags “”
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’
}
}
externalNativeBuild {
cmake {
path “CMakeLists.txt”
}
}
}

dependencies {
implementation fileTree(dir: ‘libs’, include: [‘*.jar’])
implementation ‘com.android.support:appcompat-v7:26.1.0’
implementation ‘com.android.support.constraint:constraint-layout:1.1.0’
testImplementation ‘junit:junit:4.12’
androidTestImplementation ‘com.android.support.test:runner:1.0.2’
androidTestImplementation ‘com.android.support.test.espresso:espresso-core:3.0.2’
}

CMakeLists.txt文件:

 

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
jni_FaceDetect

# Sets the library as a shared library.
SHARED

# Provides a relative path to your source file(s).
src/main/cpp/c/facedetect_main.c
src/main/cpp/c/native-lib.cpp
)

# Specifies a path to native header files.
include_directories(src/main/cpp/include/)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
log-lib

# Specifies the name of the NDK library that
# you want CMake to locate.
log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
jni_FaceDetect

# Links the target library to the log library
# included in the NDK.
${log-lib} )

facedetect_main.c:

/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the “License”);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an “AS IS” BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#define TAG “FaceDetect_JNI”
#include <com_android_camera_zf_FaceDetect.h>
#include <facedetect.h>
#include <android/log.h>
#include <stddef.h>
#include <stdio.h>

#define LOGI(…) ((void)__android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__))
#define LOGW(…) ((void)__android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__))
#define LOGE(…) ((void)__android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__))
// Log 开关
#define LOG_NDEBUG 0

/*
* Class: com_android_camera_zf_FaceDetect
* Method: tiredDetFree
* Signature: ()V
*/
void JNICALL Java_com_android_camera_zf_FaceDetect_tiredDetFree(JNIEnv *env, jclass obj){
//LOGI( ” jni tiredDetFree() “);
tiredDetFree();
}

/*
* Class: com_android_camera_zf_FaceDetect
* Method: tiredDetInit
* Signature: ()V
*/
void JNICALL Java_com_android_camera_zf_FaceDetect_tiredDetInit(JNIEnv *env, jclass obj){
LOGI( ” jni tiredDetInit() “);
tiredDetInit();
}

/*
* Class: com_android_camera_zf_FaceDetect
* Method: tiredDetProcess_new
* Signature: ([BII[I[I[I[I[I[I[I)I
*/
jint JNICALL Java_com_android_camera_zf_FaceDetect_tiredDetProcess_1new
(JNIEnv *env, jclass obj, jbyteArray jsrcData, jint jwidth, jint jheight, jintArray jopeneyes_count, jintArray jcloseeyes_count,
jintArray jfaces_count, jintArray jfaceRect, jintArray joutPts, jintArray jfacePosStatus, jintArray jfaceEdgePos){

//LOGI( ” jni tiredDetProcess_1new() “);

//srcData数据为图像yv12格式帧数据,如果只取y分量,请从srcData中截取 0—(jwidth*jheight-1)大小
//其余int*参数, size均为int[1]
jbyte* srcData = (jbyte*) (*env)->GetPrimitiveArrayCritical(env, jsrcData, 0);
jint* openeyes_count = (jint*) (*env)->GetPrimitiveArrayCritical(env, jopeneyes_count, 0);
jint* closeeyes_count = (jint*) (*env)->GetPrimitiveArrayCritical(env, jcloseeyes_count, 0);
jint* faces_count = (jint*) (*env)->GetPrimitiveArrayCritical(env, jfaces_count, 0);
jint* facePosStatus = (jint*) (*env)->GetPrimitiveArrayCritical(env, jfacePosStatus, 0);
jint* faceEdgePos = (jint*) (*env)->GetPrimitiveArrayCritical(env, jfaceEdgePos, 0);

int result = tiredDetProcess_new(srcData,jwidth,jheight,
openeyes_count, closeeyes_count,
faces_count,
NULL,//CvRect* faceRect,
NULL, //FacePts *outPts,
facePosStatus,
faceEdgePos);
(*env)->ReleasePrimitiveArrayCritical(env, jsrcData, srcData, 0);
(*env)->ReleasePrimitiveArrayCritical(env, jopeneyes_count, openeyes_count, 0);
(*env)->ReleasePrimitiveArrayCritical(env, jcloseeyes_count, closeeyes_count, 0);
(*env)->ReleasePrimitiveArrayCritical(env, jfaces_count, faces_count, 0);
(*env)->ReleasePrimitiveArrayCritical(env, jfacePosStatus, facePosStatus, 0);
(*env)->ReleasePrimitiveArrayCritical(env, jfaceEdgePos, faceEdgePos, 0);
return result;

}

//内存释放函数,只调用一次
void tiredDetFree(){
//LOGI( ” tiredDetFree() “);
}

//初始化函数,在程序启动前只调用一次
void tiredDetInit(){
LOGI( ” tiredDetInit() 111″);
}

//主处理函数
int tiredDetProcess_new(unsigned char* srcData,int width,int height,
int *openeyes_count, int *closeeyes_count,
int *faces_count,
int *faceRect,//CvRect* faceRect,
int *outPts, //FacePts *outPts,
int *facePosStatus,
int *faceEdgePos){
LOGI( ” tiredDetProcess_new() 111″);
return 0;
}



其他部分(省略)
将生成一个jni_FaceDetect.so lib文件;并在mainactivity中调用

android手机访问本地电脑Web服务器

1.android网络编程知识复习
Android的网络编程分为2种:基于http协议的,和基于socket的。Socket一般应用于社交聊天的应用中,这里关联的比较少就不讲了,我们来说说基于HTTP协议的编程。

基本原理 : 它的工作原理特别的简单,就是客户端向服务器发出一条HTTP 请求,服务器收到请求之后会返回一些数据给客户端,然后客户端再对这些数据进行解析和处理就可以了。

HTTP请求:HttpURLConnection 和 HttpClient

服务器端返回客户端的内容:
1)以HTML代码的形式返回。
2)以XML字符串的形式返回。返回的数据需要通过XML解析(SAX、DOM,Pull,等)器进行解析。
3)以json对象的方式返回。

2. HTTP请求网络数据
HttpClient在API等级22:Android 5.1 Lollipop开始被google废弃

HttpURLConnection 请求网络:

private void getXMLWithHttpURLConnection(){
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection urlConnection = null;
try {
Log.e(TAG,”开始请求网络数据…”);
URL url = new URL(“http://192.168.31.139/people.xml”);
//利用HttpURLConnection对象从网络中请求网络数据
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod(“GET”); //设置请求方式GET,POST
//设置连接超时,如果网络不好,Android系统在超过默认时间会收回资源中断操作
urlConnection.setConnectTimeout(8000);
//connection.setReadTimeout(5000); //设置读取超时
if (urlConnection.getResponseCode() != 200) {
//对响应码进行判断,200为成功
throw new RuntimeException(“请求url失败”);
}
//从Internet获取网页,发送请求,将网页以流的形式读回来
InputStream inputStream = urlConnection.getInputStream();
////对输入流进行读取
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(inputStream));
String line;
StringBuilder stringBuilder = new StringBuilder();
while ((line = bufferedReader.readLine())!=null){
stringBuilder.append(line);
}
//解析xml,下一节就讲
parseXMLWithPull(stringBuilder.toString());

} catch (Exception e) {
e.printStackTrace();
} finally {
Log.e(TAG,”关闭请求连接。”);
if (urlConnection!=null) urlConnection.disconnect();
}
}
}).start();
}

3.解析XML数据
3.1 PULL解析:

在Android上使用XmlPullParser是一中高效率和易维护解析XML的方法 。Android已经在历史上有两个实现这个接口实现类:

(1)KXmlParser,通过XmlPullParserFactory.newPullParser();
(2)ExpatPullParser,通过Xml.newPullParser();

/**
* PULL 解析 xml
* @param xmlString
*/
private void parseXMLWithPull(String xmlString){
try {
Log.d(TAG,”>>> 开始解析XML…”);
//获取XmlPullParser对象
//*种获取XmlPullParser对象的方式
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser parser = factory.newPullParser();
//第二种获取XmlPullParser对象的方式
//XmlPullParser parser=Xml.newPullParser();

parser.setInput(new StringReader(xmlString));
int eventType = parser.getEventType();
String name =”姓名”;
String age =”年龄”;
String sex =”性别”;
while (eventType !=XmlPullParser.END_DOCUMENT ){
String nodeName = parser.getName();
switch (eventType){
//开始读取XML文档 ,对应people节点
case XmlPullParser.START_DOCUMENT:
break;
// 开始解析某个结点,对应name ,age,sex标签
case XmlPullParser.START_TAG:
if (“name”.equals(nodeName)) name = parser.nextText();
if (“age”.equals(nodeName)) age = parser.nextText();
if (“sex”.equals(nodeName)) sex = parser.nextText();
break;
// 完成解析某个结点,对应person节点
case XmlPullParser.END_TAG:
if (“person”.equals(nodeName)){
Log.d(TAG,”–name is:” + name);
Log.d(TAG,”–age is:” + age);
Log.d(TAG,”–sex is:” + sex);
}
break;
default:
break;
}
eventType = parser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
}

3.2 建立本地web服务器:

讲了这么多, 到这里才跟标题挂上钩,我也是醉了。
第2节HTTP请求网络数据中的链接 http://192.168.31.139/people.xml 就是在本地建立的一个服务器里的文件,192.168.31.139就是本人的ip地址,people.xml就是我新建的xml 文件。步骤如下:

1.在http://rj.baidu.com/soft/detail/14824.html?ald 下载 Apache HTTP Server软件,下载完成后双击下载文件httpd-2.2.25-win32-x86-no_ssl.msi安装,
%title插图%num

2.在安装路径…\Apache2.2\htdocs新建people.xml文件
3.在浏览器中输入http://127.0.0.1/people.xml,即可访问到我们刚刚建立的people.xml文件内容

%title插图%num

4.值得注意的问题
在手机上访问本地电脑web服务器,设置”localhost”或者”127.0.0.1”是不行的,在模拟器上将 ip设置为”10.0.2.2”是可以访问的,但到真机上此方法行不通。

真机连接方法:1.本地电脑搭建的服务器与手机共同连接到一个无线网络下。
2.服务器端需要关闭防火墙。

%title插图%num

如何测试 Amazon Elastic File System

许多客户对 Amazon EFS 倍加推崇,因为它使得在云中创建并运行高度可扩展、高度可用且高持久性的共享文件系统变得格外轻松。只需短短数秒,就可以创建一个符合 NFSv4 的文件系统,并将其挂载到多个(多达数千个)Amazon EC2 实例或本地服务器上。

Amazon EFS 为基于 Linux 的工作负载提供了一个简单、可扩展且有弹性的文件系统,并且可在不中断应用程序的情况下按需扩展到 PB 级。Amazon EFS 支持各种使用案例,从需要*高吞吐量的高度并行、横向扩展的工作负载到单线程、延迟敏感的工作负载,不一而足。使用案例包括迁移至云上的传统企业应用程序、大数据分析、Web 服务和内容管理、应用程序开发和测试、媒体和娱乐工作流程、数据库备份和容器存储等。

我的日常工作之一是帮助客户评估、设计和实施存储解决方案以支持不同的应用程序和工作负载。我发现,那些刚开始使用 Amazon EFS 的客户对这种高级文件系统还缺乏了解。在您开始评估和测试 Amazon EFS 之前,我希望与您分享一些*佳实践。本文将帮助您充分利用 Amazon EFS。

创建 Amazon EFS 文件系统

如果您还没有创建 Amazon EFS 文件系统,请使用 AWS 管理控制台或 AWS 命令行界面 (CLI) 创建一个。完成开始使用 Amazon Elastic File System 主题中的步骤 1、2 和 3。几分钟后,您应该会登录到挂载了 Amazon EFS 文件系统的 Amazon EC2 实例。

试用

在客户挂载文件系统之后,让我们先来检查一下文件系统的大小。在挂载了 EFS 文件系统的 EC2 实例的命令行处运行 df。应会返回与下文类似的内容,这将以1KB数据库块的数量来表示文件系统大小。
在这里插入图片描述

如果您和我一样,很难直接理解一个如此庞大的数值(16 位),那么您可使用 df -h 命令来获取一个便于理解的表示。上述命令的执行结果显示您拥有 8EB 以上的可用存储。但事实上, Amazon EFS 是一个弹性文件系统,可随着您添加和删除数据自动扩展和缩减,而您只需要为实际使用的存储付费(在本例中为零)。您不再需要费心考虑如何预置存储,您只需为使用的存储付费。

在这里插入图片描述

由于 Amazon EFS 易于上手,因此您可能希望尽快深入了解并评估 Amazon EFS 的性能,一种常见的方法是使用“touch”命令测试评估 Amazon EFS 性能。这种测试会生成大量的零字节文件。我见过用 Perl、Python、Java 和其他语言编写的这类测试。

本文将使用 bash 脚本,您会看到生成 1024 个文件的速度有多快。在 EC2 实例上运行以下命令,请确保将存储路径指向已挂载的 Amazon EFS 文件系统。

time for i in {1..1024}; do
  sudo touch /mnt/efs/deleteme.$i;
  done;
  • 1
  • 2
  • 3

用了多长时间? 在我的测试中,仅用了 16.808 秒便在 Amazon EFS 上生成了 1024 个文件。

在这里插入图片描述

如果您认为生成 1024 个零字节文件所用的时间过长,请仔细检查该命令以确保其正确无误。删除*组 1024 个零字节文件后,再次运行该命令。结果如何呢? 几乎一样。

在这里插入图片描述

如果您还是认为生成 1024 个零字节文件需要的时间太长,可以将其与其他存储平台进行比较。更改命令并针对挂载到实例的 Amazon EBS 卷运行该命令。运行以下命令,确保更改路径以使用 Amazon EBS 卷。在本例中,我将写入 ec2-user 主目录。

time for i in {1..1024}; do
  sudo touch ~/deleteme.$i;
  done;
  • 1
  • 2
  • 3

用了多长时间? 在我的测试中,仅用了 5.112 秒便在 EBS 上生成了 1024 个零字节文件。这是 root 卷,即一个 10-GB gp2 EBS 卷。在本例中,与 EFS 相比,写入 EBS 的操作要快 3.28 倍。

在这里插入图片描述

在这类情况下,我会多假设几种场景。如果重新编写命令以使用多个线程会怎样? 这将允许您并行生成文件。进入 GNU Parallel,这是一个用于并行执行串行操作的开源 shell 工具。该工具已添加到 Amazon Linux 存储库中,因此在安装并启用 EPEL rpm 软件包后,可以使用 sudo yum install parallel -y 命令将其安装到 Amazon Linux 2 上。有关更多信息,请参阅 GNU Parallel。

运行以下命令,安装 GNU Parallel 并使用多个线程生成 1024 个零字节文件。

time seq 1 1024 | sudo parallel --will-cite -j 32 touch 
/mnt/efs/deleteme2.{};
  • 1
  • 2

在这里插入图片描述
将该命令重新编写为使用 32 个作业(或 32 个线程)后,仅仅在 8.647 秒内便生成了相同的 1024 个零字节文件,速度提高了 94%。

如果将多线程命令重新编写为写入多个目录会怎样? 每个线程写入一个单独的目录。这会将写入操作分布在多个 inode 上。

如果您不熟悉 inode,请注意 inode 是一种 Unix 风格的数据结构,用于描述文件系统对象,例如文件和目录。当多个线程尝试更新同一个 inode 时,会发生 inode 争用,由于存在网络延迟,这种情况在网络文件系统中更为明显。运行以下命令,使用 32 个线程生成 1024 个零字节文件,每个线程在自己的目录中生成 32 个文件。32 个目录,每个目录中包含 32 个文件,共 1024 个文件。

sudo mkdir -p /mnt/efs/{1..32}
time seq 1 32 | sudo parallel --will-cite -j 32 touch 
/mnt/efs/{}/deleteme3.{1..32};
  • 1
  • 2
  • 3

在这里插入图片描述
将命令重新编写为使用 32 个作业(或 32 个线程),并让每个线程在自己的目录中生成文件后,仅在短短 0.776 秒内便生成了 1024 个零字节文件。这比*个单线程单目录测试快了 21 倍。

如果将同一文件系统挂载到 2、10、100 或1000 个 Amazon EC2 实例,又会怎样? 如果文件系统支持关后开一致性、跨多个存储服务器和多个可用区的数据持久性以及没有单点故障的高可用性,则会生成多少个文件?

后续步骤

这只是用来有效评估和试用 Amazon EFS 的一个测试。要详细了解其性能特性,我建议您浏览一下 GitHub 上的 Amazon EFS 教程。该教程不仅包含我刚刚进行的试用,还通过更多例子说明了并行性的优势。此外,还说明了 I/O 大小、EC2 实例类型和不同的文件传输工具对性能造成的显著影响。AWS DataSync 也使用这些技术改进 EFS 文件系统往来传输数据的性能。

有关 GNU Parallel 的更多信息,请参阅 USENIX 杂志 2011 年 2 月刊上的“GNU Parallel – 强大的命令行工具”。

小结

Amazon EFS 文件系统可分布在无限量的存储服务器上,从而允许对文件系统对象进行大规模并行访问。这种分布式设计避免了传统文件服务器固有的瓶颈和约束。

在本次试用中,我利用了 Amazon EFS 的这些优势,将生成 1024 个零字节文件的时间从 16.808 秒减少到了 0.776 秒,速度提高了 2100%。

在这里插入图片描述

在本文中,我只展示了两条建议。您可以根据这些建议更好地利用 Amazon EFS 的分布式数据存储设计,并实现对文件系统数据的大规模并行访问。

*条建议是使用多个线程并行访问 EFS。第二条建议是使用多个线程并行访问多个目录或 inode。要了解有助于您更好地理解和利用 EFS 的分布式设计的其他建议,请查看 Amazon EFS 教程。

原文链接:https://aws.amazon.com/cn/blogs/china/how-to-test-drive-amazon-elastic-file-system/

Web服务器工作原理详解

概述:Web服务器概念较为广泛,我们*常说的Web服务器指的是网站服务器,它是建立在Internet之上并且驻留在某种计算机上的程序。Web服务器可以向Web客户端(如浏览器)提供文档或其他服务,只要是遵循HTTP协议而设计的网络应用程序都可以是Web客户端。

Web服务器和HTTP服务器可以说是同一个东西,当然非得细分的话,HTTP服务器是建立在HTTP协议之上的提供文档浏览的服务器,更多的是提供静态的文件。而Web服务器涵盖了HTTP服务器(这一点可以自行百度百科), Web服务器不仅能够存储信息,还能在用户通过Web浏览器提供的信息的基础上运行脚本和程序。
Web服务器 约等于 HTTP服务器 + 其他服务

目前所熟知的Web服务器有很多,其*主流的是 Apache, Nginx, IIS
各大Web服务器的实现细节都不同,是为了某种情形而设计开发的。但是它们的基础工作原理是相同的,这也是本次基础篇所讲解的内容。

一、Web服务器工作原理图解
%title插图%num

首先我们暂时不考虑HTTP协议的各种请求方式,我们先跟着**(Web服务器工作原理总体描述01)这张图,将一次Web服务的工作流程过一遍,我们假设以浏览器作为客户端
(1) 用户做出了一个操作,可以是填写网址敲回车,可以是点击链接,可以是点击按键等,接着浏览器获取了该事件。
(2) 浏览器与对端服务程序建立TCP连接。
(3) 浏览器将用户的事件按照HTTP协议格式**打包成一个数据包,其实质就是在待发送缓冲区中的一段有着HTTP协议格式的字节流。
(4) 浏览器确认对端可写,并将该数据包推入Internet,该包经过网络*终递交到对端服务程序。
(5) 服务端程序拿到该数据包后,同样以HTTP协议格式解包,然后解析客户端的意图。
(6) 得知客户端意图后,进行分类处理,或是提供某种文件、或是处理数据。
(7) 将结果装入缓冲区,或是HTML文件、或是一张图片等。
(8) 按照HTTP协议格式将(7)中的数据打包
(9) 服务器确认对端可写,并将该数据包推入Internet,该包经过网络*终递交到客户端。
(10) 浏览器拿到包后,以HTTP协议格式解包,然后解析数据,假设是HTML文件。
(11) 浏览器将HTML文件展示在页面
以上为Web服务器工作基本原理。其实不难发现,这仅仅只是一个简单的网络通信。我们应该深信,作为一个服务器,其根本的工作无非有三个

接收数据 2. 发送数据 3. 数据处理
而Web服务器的本质就是 接收数据 ⇒ HTTP解析 ⇒ 逻辑处理 ⇒ HTTP封包 ⇒ 发送数据
高级的服务器无非就是将这三个部分更加细致的设计了。
二、Web服务器之提供静态文件工作原理图解
Web服务器*主要的功能是提供静态的文件。日常的上网浏览大多是网页浏览,少数时候才会有一些数据的提交操作。因此,我们结合上一张图示来重点讲解在GET请求下的Web服务器工作原理。

%title插图%num

其他流程基本不变,着重在于红色与蓝色部分。
(1) 当用户点击一个网页链接或浏览器加载一些资源(css,jpg …)时产生。
(6) 服务程序解包后,确定其为GET请求,并且是对该服务器上的某一资源的请求。首先服务程序会去确认该路径是否存在,再确定该路径的文件是否可以获取。
(7-1) 如果请求的路径有误,或者该资源不能被用户获取,则返回错误提示页面。很多服务器的错误页面只有404,更专业的应该是将错误分类并返回对应的错误代码页面。
(7-2) 如果该路径合法且文件可以被获取,那么服务程序将根据该文件类型进行不同的装载过程,记录其类型作为(8)中HTTP协议中对应的返回类型,并加入响应头。

假设以点击一个页面链接为例,浏览器首先将HTML文件请求过来,再以同样的流程对HTML文件中包含的资源文件路径进行依次请求。

%title插图%num

三、Web服务器之数据提交工作原理图解
仅仅只是网页的浏览并不能满足所有人的需求,客户端与服务器应当是有数据交互的。
即使单方面的资源请求任然是网络的主力军。
我们应该清楚的知道,数据提交对于用户来说有什么作用。
(1) 资源上传 (2) 登陆验证 (3) API接口调用 (4) 远程指令等
数据提交使得用户的操作性有了质的飞跃,它使得HTTP短连接获取静态文件的方式提升到了动态交互的层次上。该性质也催化出各式各样的编程语言、框架。例如PHP,JavaWeb。
如果你留意目前主流的那些大型服务器,你会发现再高级再牛逼的东西实际是也是*基础的东西建造的。那么我们还可以顺便学习一下*古老的动态技术CGI
%title插图%num

其他流程基本不变,着重在于红色与蓝色部分。
(1) 用户提交数据,假设用户点击一个按键提交填好的信息。在(3)中将以POST格式写入,并填入提交至服务端的可执行程序的路径。
(6) 服务端将参数与该CGI绑定,复制进程,用管道传递参数和接收结果
(7) 子进程执行CGI,接收(6)父进程传来的参数,运算完成返回结果。
*后父进程将结果装入静态模板文件,放入缓冲区

四、动态技术
我们得明白,Web服务器是以短连接为主,并且获取的数据到达浏览器的那一刻一定是静态的不变的。那么所谓动态实际是指两种情况

服务端产生:
(1) 用户POST提交数据到某个程序,程序根据该数据作为参数运行,得出结果并装入静态的模板页面中,返回该静态页面。但对于用户来说,同一个页面,做了一个操作后数据不一样了。好了,这就是动态页面。(CGI原理)
(2) PHP的原理是,用户GET请求一个php后缀的文件,服务器先执行该php后缀文件中的PHP代码,将结果填入代码的位置,再返回。当然也可以提交数据参与运算再返回。
客户端产生:
(1) 用户GET请求一个JavaScript文件,服务端不做任何运算返回该静态文件。浏览器收到该JS文件,在本地执行并更新页面。
(2) 用户POST提交数据到服务端,服务端根据该提交的数据指令返回静态文件,浏览器收到后执行并更新。

 

AWS EC2实例Linux系统创建root用户并更改为root用户登录

对于刚创建AWS EC2实例,或者经常使用AWS 实例的小伙伴们来说,刚创建的EC2实例是没有ROOT权限的,因此不能直接使用ROOT用户去登陆实例,也无法获取到root权限。

一般情况下,EC2实例默认是以ec2-user为用户名去登陆的
(除了Ubuntu系统实例,它的默认用户名是ubuntu,centos系统实例,它的默认用户名是centos)。

对于如何去创建root及密码,以及更改用户登陆方式–改为root用户登陆实例,就显得很有必要。下文就是帮助大家如何去创建root密码,以及如何ROOT用户去登陆实例。

我用自己刚创建的ubuntu实例给大家讲解下,centos步骤通用。

在刚创建的EC2实例,我们只能使用ubuntu用户去登陆,如果尝试以ROOT用户去登陆的话,那个实例会提示下面的信息。

Please login as the user “ubuntu” rather than the user “root”.

如何创建ROOT及设置密码

输入命令:

sudo passwd root                                                                          
  • 1

然后在下面的提示中输入你为ROOT用户设置的密码

Enter new UNIX password:#输入自己设置的新密码                                               
Retype new UNIX password:#再次输入     

  • 1
  • 2
  • 3

创建完成后,使用ROOT登陆实例

输入命令:

su root
Password :   ##输入刚才设置的密码         
                                                                                                                                                       
  • 1
  • 2
  • 3

到此,我们已经成功给ROOT创建了密码,是不是很简单!

更改登陆方式,采用ROOT用户登陆

在设置之前,我们必须确保当前用户是ROOT,如果不是,依旧使用命令 ‘su root’,切换到root为实例的用户。

编辑EC2实例的ssh登录方式

编辑SSH文件 /etc/ssh/sshd_config,找到PasswordAuthentication一行,并将后面的no改为yes,再找到PermitRootLogin,同样将后面的no改为yes。*后将UsePAM 后面的yes改为no。

输入命令:

vim /etc/ssh/sshd_config                                                                                                                                                                        
  • 1

再编辑authorized_keys文件,将ssh-rsa 前面的文字全部删除,确保ssh-rsa没有任何文字,包括空格。

输入命令:

sudo vim /root/.ssh/authorized_keys            
                                           
  • 1
  • 2

在这里插入图片描述

如图 将ssh-rsa前面的 内容 全部删除 保存

重新登陆

在完成所有的设置之后,激动人心的*后一步,重启实例,重新打开putty(或者Xshell),直接使用ROOT登陆。

原文链接:
https://www.cnblogs.com/lt1993/p/10105080.html

基于HTTP实现的小型web服务器

主要流程为:服务器获得请求–>响应并处理请求–>返回结果。

完整的HTTP过渡到TCP实现客户端与服务器的交互过程
1.当客户端执行网络请求的时候,从url中解析出url的主机名,并将主机地址转换成ip
2.从url解析出服务器的所用端口号
3.客户端用TCP连接服务器
4.连接成功后 获取输出流,将数据以报文的形式传递给服务器
5.当服务器接收到数据之后,进行判断和解析码,并回应一条响应报文
6.客户端从输入流中获取报文,然后进行解析
7.关闭网络连接

HTTP的特点

1、支持客户端/服务器的模式
2、简单快捷 客户向服务器发送请求服务时,只需要传送请求方法和路径,每种方法规定了客户与服务器联系的类型的不同,由于HTTP协议简单,使得HTTP服务器的规模小,因此通信速度很快.
3、灵活  允许传送各种类型的数据,数据类型用Content-Type标记
4、无连接:限制每次连接只处理一个请求,服务器处理完客户的请求,收到客户的应答后,随即断开连接,这种方式节省传输时间,请求应答机制会断开
5、无状态  HTTP协议是无状态的协议,即对事务处理没有记忆功能

关于URL

即统一资源定位符,每个网页都对应一个URL地址(俗称网址),具有全球唯一性。它包含的信息指出文件的位置以及浏览器应该怎么处理它。 一个完整的URL包括协议类型、主机类型、路径和文件名。
http协议的URL格式: http: //host[:port][abs_path] ,http表示使用http协议来进行资源定位;host是主机域名;port是端口号,一般有默认的;abs_path代表资源的路径。
这里我主要介绍项目中涉及的URL的两种格式—URL带参数和不带参数的。
%title插图%num

HTTP的请求与响应格式

%title插图%num

响应报头中的状态码和状态码描述,例如:当请求的资源不存在时,会收到“404 NotFound”的页面,404就是状态码,“NotFound”就是状态码描述,即请求的文件不存在。

1.实现支持GET和POST方法的小型http服务器
GET方法:如果GET方法只是简单的请求一份资源,而不传递参数的话则由服务器直接将资源返回即可。如果GET方法的url中带有参数的话,则就要使用CGI模式进行处理。
POST方法:POST方法要使用CGI模式进行处理,POST的参数在消息中文中出现。
使用GET方法使用的是带参数的url,传递的参数会使用?连接在资源后面POST方法使用的是不带参数的url 它的参数是通过http请求正文传递给服务器的,http的请求和响应模式

响应报头中的状态码和状态码描述,举个例子,当请求的资源不存在的时,会收到”404 NotFound”的页面,404就是状态码,

“NotFound”就是状态码描述,既请求的文件不存在

状态码表示响应类型

1×× 保留

2×× 表示请求成功地接收

3×× 为完成请求客户需进一步细化请求

4×× 客户错误

5×× 服务器错误

响应头的信息包括:服务程序名,通知客户请求的URL需要认证,请求的资源何时能使用

 

HTTP服务器实现框架

1.面向链接:http协议是基于TCP通信协议,因此实现web服务器的*步至少要能实现两个主机不同进程之间的TCP通信,并且需要解决高并发问题所以这里推荐使用多线程服务器来构建,每次创建出来一个新线程出来的时候将线程分离,然后让这个新线程去处理这个请求.
2.分析出请求行: 当服务器接收到请求后,首先知道的是HTTP服务器版本号,和请求方法。web服务器是要支持cgi模式: 请求的方法不同,cgi可能也不同,我们实现的知识比较简单单的处理GET和POST方法
3.判断cgi模式
//    1)当我们判断出来是GET请求时候,并且url中没有参数的话,就用非CGI模式,非CGI模式处理//起来比较简单,首先解析出来请求路径,判断是不是合法资源,如果是就直接返回这个资源。
//    2)当是CGI模式处理请求的时候,我们要fork一个子进程,对子进程exec替换CGI程序,这个
//过程中使用pipe进行父子进程之间的通信。所有需要的参数在exec之前,都将这些参数导出为环境变//量,就算exec的话,子进程还是能够通过环境变量获取所需的参数。
4.响应客户端:此时我们已经知道了方法以及是否为cgi模式,然后开始读取URL,这里有一个细节非cgi模式 请求参数会跟在url当中,如果cgi模式的话,参数在消息正文中,然后我们读取到路径,判断路径当中资源是否存在,如果存在判断这个资源是一个目录,普通文件还是一个可执行程序

这里分情况分析
1)如果是cgi模式,直接进入cgi内部运行;只要是POST方法就需要支持cgi,直接进入cgi函数内部运行.
2)如果是非cgi模式时一定是GET方法并且没有参数,此时进入wwwroot()函数内部即可,该函数会将所请求的资源以html的格式返回给浏览器.

 

接下来是解释运行cgi模式,首先服务器要从浏览器读取参数,然后创建出来一个子进程去执行cgi部分的可执行资源,父进程通过环境变量的方式传递给子进程,子进程运行完成之后呢,将结果交给父进程,父进程再将数据输出给浏览器. 所以父进程在这个例子当中就向是一个中介,只进行参数和结果的转交实际上并不会执行任何资源,因此将子进程的输入输出文件描述符重定向,就可以让子进程直接与浏览器”联系”.

 

%title插图%num

父进程做的事情

1.创建两个管道,并关闭相应的文件描述符
2.POST方法:继续读取数据,直到读完POST的参数部分GET方法:直接从子进程读取结果
3.将数据和方法全部交给子进程后等待子进程的结果
子进程做的事情

1.关闭管道适当的文件描述符
2.对标准输入输出进行重定向
3.通过环境变量传递参数
4.进行exec程序替换

一次完整的http请求的流程
%title插图%num

项目文件

%title插图%num

目录:
python:爬取小说和招聘信息的代码

sql_connect:存放mysql需要的lib库   连接mysql程序文件
wwwroot:web服务器工作的根目录,包含各种资源页面(例如默认的index.html页面,差错处理的404页面),以及执行cgi的可执行程序

文件:

makefile:编译整个项目
httpd.h:服务器的方法声明
httpd.c:方法实现
main.c:服务器的主逻辑

 

数据库中的操作
没有索引的时候会进行整个表的扫描
添加索引 索引会形成一颗二叉树  利用二分查找的方法。

遇到的问题:
1.运行cgi后不能显示在页面上,便尝试着写一个简单的CGI程序看自己的CGI是否真的能跑完,结果CGI没有问题,后来尝试用telnet工具模拟一次http,看看是否真的收到了网页回复,后来分析结果,对比之后发现返回的东西不能显示,之后给html加了一些p标签,便可以显示出来。
2. 经常会出现类似于:undefined reference to `sql_connecter::~sql_connecter()’的问题,文件编译的路径不对。
3.调用数据库的数据显示到html文件中出现乱码的问题,*初以为自己编码格式有问题,后来发现是数据库编码格式和浏览器的编码格式不一样,数据库使用utf8编码方式,浏览器是GB2312,后来浏览器使用utf8编码格式,能够正常显示。

4.代码中会需要int *和 void*的转换,用到C++强制转换形如  int*  data = reinterpret_cast<int*>(arg);

5.本地环回测试ok,Linux下的浏览器测试也可以,但不能接外部的浏览器访问(没有设置桥接模式) 在外部浏览器测试的话千万别忘记关闭防火墙

6.运行程序时会提醒挺行下载页面,因为在响应报头有问题中。而浏览器对于不能识别或解析的实体,都会提醒用户下载。

常见Web服务器简介

Web服务器也称为WWW (WORLD WIDE WEB)服务器、HTTP服务器,其主要功能是提供网上信息浏览服务。

Unix和Linux平台下的常用Web服务器有Apache,Nginx,Lighttpd,Tomcat,IBM WebSphere、BEA Weblogic等,其中应用*广泛的是Apache。而WindowsNT/2000/2003平台下*常用的服务器则是微软公司的IIS C Internet Information Server )。

下面对常见的WEB服务器进行简单介绍,后续对其中一些主要的服务器进行实际环境搭建。

1.  Apache服务器

%title插图%num

Apache仍然是世界上用得*多的Web服务器,市场占有率达60%左右。它源于NCSAhttpd服务器,在NCSA WWW服务器项目停止后,那些使用NCSA WWW服务器的人们开始交换用于此服务器的补丁,这也是Apache名称的由来(pache补丁)。世界上很多著名的网站都是Apache的用户,它的优势主要在于源代码开放、有一支开放的开发队伍、支持跨平台的应用(可以运行在几乎所有的Unix, Windows. Linux系统平台上),以及其可移植性等。Apache的模块支持非常丰富,虽在速度、性能上不及其他轻量级W eb服务器,但是属于重量级产品,所消耗的内存也比其他Web服务器要高。

官方网站:http://httpd.apache.org/

2. Nginx服务器

%title插图%num

罗斯访问量第二的 Rambler.ru 站点开发的,*个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。

Nginx(发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协议下发行。由俄罗斯的程序设计师Igor Sysoev所开发,供俄国大型的入口网站及搜索引擎Rambler(俄文:Рамблер)使用。其特点是占有内存少,并发能力强,是目前市面上唯一能和kangleweb server比拼的web server,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:新浪、网易、腾讯等。

官方网站:http://nginx.org/

3.  Tomcat服务器

%title插图%num

Tomcat是一个开放源代码、运行servlet和JSP Web应用软件的基于Java的W eb应用软件容器。Tomcat Server是根据servlet和JSP规范执行的,因此也可以说Tomcat Server实行了Apache-Jakarta规范,且比*大多数商业应用软件服务器要好。但是,Tomcat对静态文件、高并发的处理比较弱。

官方网站:http://tomcat.apache.org

4.  Lighttpd服务器

%title插图%num

Lighttpd是由一个德国人写的开源软件,其目标是提供一个专门针对高性能网站,安全、快速、兼容性好并且灵活的Web  Server环境。它具有内存开销低、CPU占用率低、效能好,以及模块丰富等特点。支持FastCGI、CGI. Auth、输出压缩(output compress )、URL重写及Alias等重要功能。Lighttpd跟Nginx一样,也是一款轻量级Web服务器,是Nginx的竞争对手之一。

官方网站:http://www.lighttpd.net/

5.  Microsoft IIS 服务器

%title插图%num

Microsoft的W eb服务器产品为Internet Information Server C IIS ) .  IIS是允许在公共Intranet或Internet上发布信息的Web服务器。它是目前*流行的Web服务器产品,很多著名的网站都是建立在IIS平台上的。IIS提供了一个图形界面的管理工具,称为Internet服务管理器,可用于监视配置和控制Internet服务。

IIS是一种Web服务组件,其中包括Web服务器、FTP服务器、NNTP服务器和SMTP服务器,分别用于网页浏览、文件传输、新闻服务和邮件发送等方面,它使得在网络(包括互联网和局域网)上发布信息成了一件很容易的事。它提供ISAPI ( Intranet Server API)作为扩展Web服务器功能的编程接口;同时,它还提供一个Internet数据库连接器,可以实现对数据库的查询和更新。

IIS只能运行在Microsoft Windows平台、LinuxNnix平台上,因此须要购买商业的Windows Server操作系统。

演示网站:http://www.yangyufei.com

6.  IBM WebSphere服务器

%title插图%num

WebSphere Application Server是一种T}}能完善、开放的Web应用程序服务器,是IBM电子商务计}}J的核心部分,它基于Java的应用环境,建立、部署和管理Internet和Intranet Web应用程序。这一整套产品目前己进行了扩展,以适应Web应用程序服务器的需要,范围从简单到高级,直到企业级。据IBM官方网站介绍,有10 000多个企业正在使用IBM WebSphere,相对于其他流行的Web服务器而言,应用的数量很少。

官方网站:http://www.ibm.com/developerworks/cn/websphere

7.  Oracle Weblogic服务器

%title插图%num

WebLogic是美商Oracle的主要产品之一,系并购得来。是商业市场上主要的Java(J2EE)应用服务器软件(applicationserver)之一,是世界上*个成功商业化的J2EE应用服务器, 已推出到12c(12.1.1) 版。而此产品也延伸出WebLogic Portal, WebLogic Integration等企业用的中间件(但当下Oracle主要以Fusion Middleware融合中间件来取代这些WebLogic Server之外的企业包),以及OEPE(Oracle Enterprise Pack for Eclipse)开发工具。

WebLogic*早由 WebLogic Inc. 开发,后并入BEA 公司,*终BEA公司又并入 Oracle公司。

webserver是用来构建网站的必要软件。可用来解析、发布网页等功能,它是用纯java开发的。weblogic本来不是由bea发明的,是它从别人手中买过来,然后再加工扩展。BEA已经被Oracle收购,目前Weblogic*新版本为Oracle Weblogic Server 12c(12.1.1)。其他J2EE Application Server还有IBM的websphere、Sun(Sun公司已经被ORACLE公司收购)的Glassfish、resin等。Apache Tomcat也是常用的Servlet/JSP Container。国内厂商生产的还有像中创软件的Loong AS 9.0(达四级等保,全面支持国产)、东方通的Tongweb、金蝶Apusic应用服务器等。

BEA WebLogicServer拥有处理关键Web应用系统问题所需的性能、可扩展性和高可用性。

与BEA WebLogic Commerce ServerTM配合使用,BEA WebLogic Server可为部署适应性个性化电子商务应用系统提供完善的解决方案。

WebLogic长期以来一直被认为是市场上*好的J2EE工具之一。像数据库或邮件服务器一样,WebLogic Server 对于客户是不可见的,为连接在它上面的客户提供服务。WebLogic *常用的使用方式是为在internet 或intranet 上的Web 服务提供安全、数据驱动的应用程序。WebLogic对J2EE 架构的支持:WebLogic Server 提供了对SUN J2EE 架构的支持。SUN公司的J2EE 架构是为企业级提供的一种支持分布式应用的整体框架。为集成后端系统,如ERP系统,CRM系统,以及为实现企业级计算提供了一个简易的,开放的标准。

官方网站:http://www.oracle.com/us/corporate/acquisitions/bea/index.html

8.  Boa服务器

%title插图%num

BOA 服务器是一个小巧高效的web服务器,是一个运行于unix或linux下的,支持CGI的、适合于嵌入式系统的单任务的http服务器,源代码开放、性能高。由于它是一个单任务的Web服务器,只能一次完成用户的请求,而不会fork出新的进程来处理并发的链接请求。但是Boa支持Cgi,能够为Cgi程序fork出一个进程来执行相应的客户请求。

官方网站:http://www.boa.org/

9.  W3C  Jigsaw服务器

Jigsaw是W3C推出的开源的Web服务器平台,使用Java语言编写,可以安装在有Java运行环境的系统上。做为W3C(World WideWeb Consortium)开发的服务器产品,其作用主要是对新技术的实现做一个示例,而非全功能的商业服务器产品。

不过就Jigsaw 2.0版本而言,它的功能还是超过了目前Web服务器的平均水平。*重要的是,它体现了未来HTTP协议和基于对象的Web服务器技术的发展。如果你希望你的平台支持所有下一代技术,Jigsaw是一个好的选择。

官方网站:http://www.w3.org/Jigsaw/

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速