Android内存优化 了解java内存分配

Android内存优化-了解java内存分配

JVM内存模型

Java虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是:
1. 程序计数器
2. Java虚拟机栈
3. 本地方法栈
4. 堆
5. 方法区。

下面对这五个区域展开深入的介绍。

1. 程序计数器

1.1. 什么是程序计数器?

程序计数器是一块较小的内存空间,可以把它看作当前线程正在执行的字节码的行号指示器。也就是说,程序计数器里面记录的是当前线程正在执行的那一条字节码指令的地址。
注:但是,如果当前线程正在执行的是一个本地方法,那么此时程序计数器为空。

1.2. 程序计数器的作用

程序计数器有两个作用:

  1. 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
  2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。

1.3. 程序计数器的特点

  1. 是一块较小的存储空间
  2. 线程私有。每条线程都有一个程序计数器。
  3. 是唯一一个不会出现OutOfMemoryError的内存区域。
  4. 生命周期随着线程的创建而创建,随着线程的结束而死亡。

2. Java虚拟机栈(JVM Stack)

2.1. 什么是Java虚拟机栈?

Java虚拟机栈是描述Java方法运行过程的内存模型。
Java虚拟机栈会为每一个即将运行的Java方法创建一块叫做“栈帧”的区域,这块区域用于存储该方法在运行过程中所需要的一些信息,这些信息包括:

  1. 局部变量表
    存放基本数据类型变量、引用类型的变量、returnAddress类型的变量。
  2. 操作数栈
  3. 动态链接
  4. 方法出口信息

当一个方法即将被运行时,Java虚拟机栈首先会在Java虚拟机栈中为该方法创建一块“栈帧”,栈帧中包含局部变量表、操作数栈、动态链接、方法出口信息等。当方法在运行过程中需要创建局部变量时,就将局部变量的值存入栈帧的局部变量表中。
当这个方法执行完毕后,这个方法所对应的栈帧将会出栈,并释放内存空间。

注意:人们常说,Java的内存空间分为“栈”和“堆”,栈中存放局部变量,堆中存放对象。
这句话不完全正确!这里的“堆”可以这么理解,但这里的“栈”只代表了Java虚拟机栈中的局部变量表部分。真正的Java虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。

2.2. Java虚拟机栈的特点

  1. 局部变量表的创建是在方法被执行的时候,随着栈帧的创建而创建。而且,局部变量表的大小在编译时期就确定下来了,在创建的时候只需分配事先规定好的大小即可。此外,在方法运行的过程中局部变量表的大小是不会发生改变的。
  2. Java虚拟机栈会出现两种异常:StackOverFlowError和OutOfMemoryError。
    a) StackOverFlowError:
    若Java虚拟机栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前Java虚拟机栈的*大深度的时候,就抛出StackOverFlowError异常。
    b) OutOfMemoryError:
    若Java虚拟机栈的内存大小允许动态扩展,且当线程请求栈时内存用完了,无法再动态扩展了,此时抛出OutOfMemoryError异常。
  3. Java虚拟机栈也是线程私有的,每个线程都有各自的Java虚拟机栈,而且随着线程的创建而创建,随着线程的死亡而死亡。

注:StackOverFlowError和OutOfMemoryError的异同?
StackOverFlowError表示当前线程申请的栈超过了事先定好的栈的*大深度,但内存空间可能还有很多。
而OutOfMemoryError是指当线程申请栈时发现栈已经满了,而且内存也全都用光了。

3. 本地方法栈

3.1. 什么是本地方法栈?

本地方法栈和Java虚拟机栈实现的功能类似,只不过本地方法区是本地方法运行的内存模型。

本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。

方法执行完毕后相应的栈帧也会出栈并释放内存空间。

也会抛出StackOverFlowError和OutOfMemoryError异常。

4. 堆

4.1. 什么是堆?

堆是用来存放对象的内存空间。
几乎所有的对象都存储在堆中。

4.2. 堆的特点

  1. 线程共享
    整个Java虚拟机只有一个堆,所有的线程都访问同一个堆。而程序计数器、Java虚拟机栈、本地方法栈都是一个线程对应一个的。
  2. 在虚拟机启动时创建
  3. 垃圾回收的主要场所。
  4. 可以进一步细分为:新生代、老年代。
    新生代又可被分为:Eden、From Survior、To Survior。
    不同的区域存放具有不同生命周期的对象。这样可以根据不同的区域使用不同的垃圾回收算法,从而更具有针对性,从而更高效。
  5. 堆的大小既可以固定也可以扩展,但主流的虚拟机堆的大小是可扩展的,因此当线程请求分配内存,但堆已满,且内存已满无法再扩展时,就抛出OutOfMemoryError。

5. 方法区

5.1. 什么是方法区?

Java虚拟机规范中定义方法区是堆的一个逻辑部分。
方法区中存放已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。

5.2. 方法区的特点

  1. 线程共享
    方法区是堆的一个逻辑部分,因此和堆一样,都是线程共享的。整个虚拟机中只有一个方法区。
  2. 永久代
    方法区中的信息一般需要长期存在,而且它又是堆的逻辑分区,因此用堆的划分方法,我们把方法区称为老年代。
  3. 内存回收效率低
    方法区中的信息一般需要长期存在,回收一遍内存之后可能只有少量信息无效。
    对方法区的内存回收的主要目标是:对常量池的回收 和 对类型的卸载。
  4. Java虚拟机规范对方法区的要求比较宽松。
    和堆一样,允许固定大小,也允许可扩展的大小,还允许不实现垃圾回收。

5.3. 什么是运行时常量池?

方法区中存放三种数据:类信息、常量、静态变量、即时编译器编译后的代码。其中常量存储在运行时常量池中。

我们一般在一个类中通过public static final来声明一个常量。这个类被编译后便生成Class文件,这个类的所有信息都存储在这个class文件中。

当这个类被Java虚拟机加载后,class文件中的常量就存放在方法区的运行时常量池中。而且在运行期间,可以向常量池中添加新的常量。如:String类的intern()方法就能在运行期间向常量池中添加字符串常量。

当运行时常量池中的某些常量没有被对象引用,同时也没有被变量引用,那么就需要垃圾收集器回收。

6. 直接内存

直接内存是除Java虚拟机之外的内存,但也有可能被Java使用。

在NIO中引入了一种基于通道和缓冲的IO方式。它可以通过调用本地方法直接分配Java虚拟机之外的内存,然后通过一个存储在Java堆中的DirectByteBuffer对象直接操作该内存,而无需先将外面内存中的数据复制到堆中再操作,从而提升了数据操作的效率。

直接内存的大小不受Java虚拟机控制,但既然是内存,当内存不足时就会抛出OOM异常。

综上所述

      1. Java虚拟机的内存模型中一共有两个“栈”,分别是:Java虚拟机栈和本地方法栈。
        两个“栈”的功能类似,都是方法运行过程的内存模型。并且两个“栈”内部构造相同,都是线程私有。
        只不过Java虚拟机栈描述的是Java方法运行过程的内存模型,而本地方法栈是描述Java本地方法运行过程的内存模型。
      2. Java虚拟机的内存模型中一共有两个“堆”,一个是原本的堆,一个是方法区。方法区本质上是属于堆的一个逻辑部分。堆中存放对象,方法区中存放类信息、常量、静态变量、即时编译器编译的代码。
      3. 堆是Java虚拟机中*大的一块内存区域,也是垃圾收集器主要的工作区域。
      4. 程序计数器、Java虚拟机栈、本地方法栈是线程私有的,即每个线程都拥有各自的程序计数器、Java虚拟机栈、本地方法区。并且他们的生命周期和所属的线程一样。
        而堆、方法区是线程共享的,在Java虚拟机中只有一个堆、一个方法栈。并在JVM启动的时候就创建,JVM停止才销毁。

Android性能调优篇之探索JVM内存分配

Android性能调优篇之探索JVM内存分配

开篇废话

今天我们一起来学习JVM的内存分配,主要目的是为我们Android内存优化打下基础。

一直在想以什么样的方式来呈现这个知识点才能让我们易于理解,*终决定使用方法为:图解+源代码分析

 

希望能在我们平时开发写代码的时候,能够知道当前写的这段代码,内存方面是如何分配的。

我们深知,一个Java程序员在很多时候根本不用操心内存的释放,而是依靠JVM去管理,以前写C++代码的时候,却要时刻记着new的空间要及时释放掉,不然程序很容易出现内存溢出的情况。因为,Java在这方面确实方便了许多,让我们有更多精力去考虑业务方面的实现。但是,这并不意味着我们就能肆无忌惮的使用内存,因为:

1.JVM并不会及时的去清理内存

2.我们无法通过代码去控制JVM去清理内存

这就要求我们平时在开发过程中,要了解JVM的垃圾回收机制,合理安排内存。

那么怎么样才能合理安排内存呢?那么就需要我们了解JVM的内存分配机制,而后才能真正控制好,让程序运行在我们鼓掌之中。


技术详情

1.JVM内存模型

平时我们对于Java内存都有一个比较粗略的概念,就是分堆和栈,但实际上还是复杂得多,以下给出完整内存模型:

内存模型

内存模型

相对应区域的内容为:

内容模型

内容模型

1.1程序计数器PC

这一个区域我概括了以下几个要点:

1.这一区域不会出现OOM(Out Of Memory)错误的情况

2.属于线程私有,因为每一个线程都有自己的一个程序计数器,来表示当前线程执行的字节码行号

3.标识Java方法的字节码地址,而不是Native方法

4.处于CPU上,我们无法直接操作这块区域


1.2虚拟机栈

这个区域也是我们平时口中说的堆栈的栈,关于这个块区域有如下要点:

1.属于线程私有,与线程的生命周期相同

2.每一个java方法被执行的时候,这个区域会生成一个栈帧

4.栈帧中存放的局部变量有8种基本数据类型,以及引用类型(对象的内存地址)

5.java方法的运行过程就是栈帧在虚拟机栈中入栈和出栈的过程

6.当线程请求的栈的深度超出了虚拟机栈允许的深度时,会抛出StackOverFlow的错误

7.当Java虚拟机动态扩展到无法申请足够内存时会抛出OutOfMemory的错误

1.3本地方法栈

这个区域,属于线程私有,顾名思义,区别于虚拟机栈,这里是用来处理Native方法(Java本地方法)的,而虚拟机栈是处理Java方法的。对于Native方法,Object中就有不少的Native的方法,hashCode,wait等,这些方法的执行很多时候都是借助于操作系统。

这一区域也有可能抛出StackOverFlowError 和 OutOfMemoryError

1.4 Java堆

我们平时说得*多,关注得*多的一个区域,就是他了。我们后期进行的性能优化主要针对这部分内存,GC的主战场,这个地方存放的几乎所有的对象实例和数组数据。这里我大概进行了如下概括:

1.Java堆属于线程共享区域,所有的线程共享这一块内存区域

2.从内存回收角度,Java堆可被分为新生代和老年代,这样分能够更快的回收内存

3.从内存分配角度,Java堆可划分出线程私有的分配缓存区(Thread Local Allocation Buffer,TLAB),这样能够更快的分配内存

4.当Java虚拟机动态扩展到无法申请足够内存时会抛出OutOfMemory的错误

1.5 方法区

方法区主要存放的是已被虚拟机加载的类信息、常量、静态变量、编译器编译后的代码等数据。GC在该区域出现的比较少。概括如下:

1.方法区属于线程共享区域

2.习惯性加他永久代

3.垃圾回收很少光顾这个区域,不过也是需要回收的,主要针对常量池回收,类型卸载

4.常量池用于存放编译期生成的各种字节码和符号引用,常量池具有一定的动态性,
  里面可以存放编译期生成的常量

5.运行期间的常量也可以添加进入常量池中,比如string的intern()方法。


1.6 运行时常量池

运行时常量池也是方法区的一部分,用于存放编译器生成的各种字面量和符号引用。单独拿出来说明一下,是因为我们平时使用String比价多,涉及到这一块的知识,但这一块区域不会抛出OutOfMemoryError

2.JVM内存源码示例说明

首先写了一个main方法,来做演示,代码如下:

package senduo.com.memory.allocate;

/**
 * *****************************************************************
 * * 文件作者:ouyangshengduo
 * * 创建时间:2017/8/11
 * * 文件描述:内存分配调用过程演示代码
 * * 修改历史:2017/8/11 9:39*************************************
 **/
public class MemoryAllocateDemo {
    public static void main(String[] args){ //JVM自动寻找main方法
        /**
         * 执行*句代码,创建一个Test实例test,在栈中分配一块内存,存放一个指向堆区实例对象的指针
         */
        Test test = new Test();
        
        /**
         * 执行第二句代码,声明定义一个int型变量(8种基本数据类型),在栈区直接分配一块内存存储这个变量的值
         */
        int date = 9;
        
        /**
         * 执行第三句代码,创建一个BirthDate实例bd1,在栈中分配一块内存,存放一个指向堆区实例对象的指针
         */
        BirthDate bd1 = new BirthDate(13,6,1991);
        
        /**
         * 执行第四句代码,创建一个BirthDate实例bd2,在栈中分配一块内存,存放一个指向堆区实例对象的指针
         */
        BirthDate bd2 = new BirthDate(30,4,1991);
        
        /**
         * 执行第五句代码,方法test1入栈帧,执行完出栈
         */
        test.test1(date);
        
        /**
         * 执行第六句代码,方法test2入栈帧,执行完出栈
         */
        test.test2(bd1);
        
        /**
         * 执行第七句代码,方法test3入栈帧,执行完出栈
         */
        test.test3(bd2);

    }
}

演示过程一

1.JVM自动寻找main方法,执行*句代码,创建一个Test类的实例test,
  在栈中分配一块内存,存放一个指向堆区对象的指针110925。

2.创建一个int型的变量date,由于是基本类型,直接在栈中存放date对应的值9。

3.创建两个BirthDate类的实例bd1、bd2,在栈中分别存放了对应的指针指向各自的对象
  ,他们在实例化时调用了有参数的构造方法,因此对象中有自定义初始值。
  

图解如下:

内存分配调用演示一

内存分配调用演示一

演示过程二

1.test1方法入栈帧,以date为参数

2.value为局部变量,把value放在栈中,并且把date的值赋值给value

3.123456赋值给value局部变量

4.test1方法执行完,value内存被释放,test1方法出栈
内存分配调用演示二

内存分配调用演示二
内存分配调用演示二

内存分配调用演示二
内存分配调用演示二

内存分配调用演示二

演示过程三

1.test2方法入栈帧,以实例bd1为参数

2.birthDate为局部变量,把birthDate放在栈中,把bd1的引用的值赋值给birthDate,
  也就是bd1与birthDate的地址都是指向同一个堆区的实例
3.在堆区new了一个对象,并且把这个堆区的指针保存在栈区中birthDate对应的内存空
  间,这个时候,bd1与birthDate指向了不同的堆区,那么birthDate的改变,并不会对
  bd1造成影响

4.test2方法执行完,栈中的birthDate空间被释放,test2方法出栈,但堆区的内存空间
  则要等待系统自动回收
内存分配调用演示三

内存分配调用演示三
内存分配调用演示三

内存分配调用演示三
内存分配调用演示三

内存分配调用演示三

演示过程四

1.test3方法入栈帧,以实例bd2为参数

2.birthDate为局部变量,把birthDate放在栈中,把bd2的引用的值赋值给birthDate,
  也就是bd2与birthDate的地址都是指向同一个堆区的实例
3.调用birthDate的setDay方法,因为birthDate与bd2指向的是同一个对象,也就是bd2调用了setDay方法,所以,也会bd2造成影响

4.test3方法执行完,栈中的birthDate空间被释放,test3方法出栈

内存分配调用演示四

内存分配调用演示四
内存分配调用演示四

内存分配调用演示四
内存分配调用演示四

内存分配调用演示四

3.JVM内存分配小结

跟着上面四个步骤,走一遍,会发现其实也不会那么复杂,掌握思想就能摸到门路了,我们平时注意区分一下基本数据类型的变量和引用数据类型变量,以下进行了几点概括:

1.局部变量中的基本数据类型的值直接存栈中

2.局部变量中的引用数据类型在栈中存的是引用类型的指针(地址)

3.栈中的数据与堆中的数据内存回收并不是同步的,栈中的只要方法运行完,就会直接
  销毁局部变量,但堆中的对象不一定立即销毁
  
4.类的成员变量在不同对象中各不相同,都有自己的存储空间(成员变量在堆中的对象中
  )。而类的方法却是该类的所有对象共享的,只有一套,对象使用方法的时候方法才被
  压入栈,方法不使用则不占用内存

干货总结

终于把JVM内存分配的分享写完了,一路写下来,确实对内存分配又深入了解了一次。期间参考了以下:

Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收

Java 内存分配全面浅析

Jvm内存模型

通过对JVM内存模型的认识后,下一章将进行JVM垃圾回收机制的探索。

怎么样测试站点能承受多大并发?

比如我的站点,是阿里云的, 1G 内存, 1 核 CPU , 1M 带宽,而且数据库, redis , nginx 都装在本机上,挂了一个站点,访问的人不是很多,所以平时打开秒开。但是我怎么测这样的配置能顶住多少并发呢?

或者根据什么参数来计算。对这方面不是很有经验,求赐教!!(www.tanteng.me)

第 1 条附言 · 2016-06-22 22:49:08 +08:00
ddos

站点 赐教 Redis Nginx17 条回复
qgy18 1
qgy18 2016-06-22 21:49:23 +08:00 via iPhone
既然你都把网址发到了 v2 全球压测系统,那等着看你的站会不会挂就知道并发能力了。
UnisandK 2
UnisandK 2016-06-22 21:52:28 +08:00
@qcloud 他会告诉你的
jugelizi 3
jugelizi 2016-06-22 21:54:54 +08:00
@qgy18 人家就是钓鱼的
lincanbin 4
lincanbin 2016-06-22 21:56:18 +08:00
如果你的静态资源是存放在 CDN 上的话,用户访问对于服务器的压力也就只有动态请求了。
那么可以使用 Apache Benchmark 来测试。

如果没用 CDN 的话,其实静态资源对于性能的消耗也不大,一般来说,测试得到的并发数*90%就差不多了。
qcloud 5
qcloud 2016-06-22 22:35:06 +08:00
@UnisandK 一言不合就躺枪
iamwb 6
iamwb 2016-06-22 22:40:16 +08:00 via Android
放 hostloc 免费压测啊
800126 7
800126 2016-06-22 22:45:36 +08:00
目测已经挂了。。
9hills 8
9hills 2016-06-22 22:45:44 +08:00
呀,好像挂了, lz 有记录*大并发么
qq915458022 9
qq915458022 2016-06-22 22:48:52 +08:00 via Android
效果如图?: http://imgur.com/z3fbYmR
tanteng 10
tanteng 2016-06-22 22:49:47 +08:00
已遭 DDOS 攻击,原来服务器这么脆弱,怎么防?
9hills 11
9hills 2016-06-22 22:50:29 +08:00
@tanteng 阿里不是给你提示了么,买云盾啊
tanteng 12
tanteng 2016-06-22 22:52:37 +08:00
@9hills 推荐的购买高防 IP ,*低价一个月都是几十万,怎么这玩意这么贵
9hills 13
9hills 2016-06-22 22:55:18 +08:00
@tanteng 因为攻击成本也很高啊。。。

回到正题,简单的 web 站用 ab 测试下就好了。。用 google 搜 ab apache
tanteng 14
tanteng 2016-06-22 23:00:07 +08:00
现在网站已挂,遭受 DDOS 攻击,这种攻击怎么在服务器层面防范呢,设置防火墙吗
lhbc 15
lhbc 2016-06-22 23:10:50 +08:00
假如静态资源没有使用 CDN
平均每个页面 500K ,其中 50K 是动态生成的页面, 450K 是静态资源,设置了 cache-control: max-age=n
查下新访客占比
不考虑服务器存在性能瓶颈,那其实已经能算出峰值能承受的并发数了

*端情况就是所有都是老访客,所有静态资源都在访客的浏览器有缓存,也就是 1M / 8 / 50K = 2.5 QPS

如果来一个新访客,单是一个 500K 的页面就需要 4 秒钟传输
wdlth 16
wdlth 2016-06-22 23:22:36 +08:00
可以先用 SendGrid 的那个 loader.io 测测,有次试了一点时间,结果欠了 10 多 G CDN 流量……
tanteng 17
tanteng 2016-06-23 09:36:30 +08:00
DDOS 真是网络的一大威胁,而且对于我这种站点来说没办法防啊,不过这种站点也不会有多少攻击,大网站真的安全很重要,这一挂就损失大了,终于明白服务器,还有运维的重要性!

阿里云的 ECS 服务器重启一下要一个小时?

阿里云的服务器某个分区容量达到 100%了,我把几十 G 的文件转移到另一个分区,然而这个分区还是显示 100%,我 TM 就想,是不是要重启服务器了,然后就重启了,等了快一个小时,服务器还是连不上,我就问客服,什么情况啊?

等了半天客服发来一张图,说“您系统当前处在磁盘加载中”。。。。。上面显示磁盘只加载了 42%!!!!!!

是不是意味着,我再等一个小时,磁盘就能加载完啊!!!

我就想问一下,阿里云的硬盘是什么做的?重启一下为什么要这么久?

磁盘 服务器 分区 阿里云7 条回复 • 2016-06-22 11:15:31 +08:00
Yourdaye 1
Yourdaye 2016-06-22 10:26:24 +08:00
看到 V2EX 很多人吐槽阿里云的服务器,看来我不是一个人在战斗
qcloud 2
qcloud 2016-06-22 10:28:52 +08:00
233 *近阿里云?
jamesxu 3
jamesxu 2016-06-22 10:29:15 +08:00
我记得*次新建 ECS 时,用的 Windows Server 2008 R2 ,结果管理员密码登不进去,让客服搞了下也不行,*后重装了,好在当时里面什么都没有
Yourdaye 4
Yourdaye 2016-06-22 10:42:24 +08:00
@qcloud 真是怕了……原以为阿里云是个值得信赖的大公司,没想到……
qcloud 5
qcloud 2016-06-22 10:46:19 +08:00
@Yourdaye 来腾讯云把
mml 6
mml 2016-06-22 11:06:52 +08:00
腾讯云和阿里云是一个级别的垃圾。别问我为啥知道的。
Yourdaye 7
Yourdaye 2016-06-22 11:15:31 +08:00
@mml 我觉得 linode 非常好,如果世界上没有墙

阿里云租几台机器做采集,有现成调度方案吗?

打算租几台阿里云的服务器采集数据,好处是:多 IP ,带宽有保证。 如果抓取的网站封 IP ,限时间,就再开一台云服务器。 不知道有没有一个动态调度的方案,发现 IP 被封了,再开一台服务器获得新 IP ,再抓取。阿里云提供接口做这个吗?

18 条回复    2016-06-26 23:00:19 +08:00
fcicq
    1

fcicq   2016-06-26 14:23:12 +08:00

封到 /16 的 block 的话就抓瞎了, 明摆着人家能看到你是租的
l0wkey
    2

l0wkey   2016-06-26 14:24:06 +08:00

用弹性 IP
ZGLHHH
    3

ZGLHHH   2016-06-26 14:27:22 +08:00

为什么不买拨号 VPS 呢
rekulas
    4

rekulas   2016-06-26 14:52:45 +08:00

可以自己写脚本,封了自己申请 vps ,镜像复原

但是还是没有代理来的方便便宜,直接购买代理多线程抓取,也不怕封价格也便宜

lmaq
    5

lmaq   2016-06-26 16:04:25 +08:00

阿里云有 API
crab
    6

crab   2016-06-26 16:35:47 +08:00

@rekulas 现在代理不管付费还是免费,大部分都是失效快响应慢。这种用带 ADSL 拨号的 VPS 是*合适的。
odirus
    7

odirus   2016-06-26 18:01:20 +08:00

阿里的 API ? 反正我是挺讨厌的。

但他有个弹性伸缩服务,能够定时伸缩服务器数量。制作好镜像,然后从镜像中安装系统

但有个问题,他的*小时间粒度貌似是小时(前段时间验证的,现在不知道改没有)

可以考虑一下国内其他的云,秒级调度 + 弹性伸缩,不知道青云是不是?好奇,求解答

aheadlead
    8

aheadlead   2016-06-26 18:06:36 +08:00

@odirus 青云是的
boter
    9

boter   2016-06-26 18:28:45 +08:00 via iPhone

直接买袜子多好
nine
    10

nine   2016-06-26 18:35:14 +08:00

tangzhehao
    11

tangzhehao   2016-06-26 19:14:20 +08:00

@odirus 有谁家可以纵向弹性伸缩么?也就是增配不增量。
@aheadlead
aheadlead
    12

aheadlead   2016-06-26 19:28:44 +08:00

@tangzhehao 这连个 VPS 都可以吧… 青云肯定是可以的
zava
    13

zava   2016-06-26 19:58:17 +08:00   ❤️ 1

不用这么麻烦吧,直接买一些 http 代理,便宜量又足。当然可用率是要打点折扣的。
我用过的几个比较靠谱的 http 代理:

1. 快代理: http://www.kuaidaili.com/
2. 中国 IP 代理: http://cn-proxy.com/
3. 酷伯伯 HTTP 代理: http://www.coobobo.com

另外,如果都使用阿里云的 IP 进行采集,也不一定是 100%可靠,具体就不细说了……

tangzhehao
    14

tangzhehao   2016-06-26 19:59:48 +08:00

@aheadlead 不是,要自动的,就像弹性伸缩一样,譬如监控连报 3 次 CPU>85%,那就立马升配一核。
TangMonk
    15

TangMonk   2016-06-26 20:06:33 +08:00

青云关机只收取硬盘费用,不做 web 服务,只做采集的话可以定时关机,还是挺划得来的
odirus
    16

odirus   2016-06-26 20:49:01 +08:00   ❤️ 1

http://www.freeproxylists.net/zh/

这个代理质量高很多,快代理那个质量。。。买过,不会再买了。

aheadlead
    17

aheadlead   2016-06-26 21:59:33 +08:00

@tangzhehao 阿里云有个 ESS 可以动态加机器数量(横向扩展)
貌似也是支持你想要的纵向扩展 你可以试着去看看

其实这个不难写啊 如果只是临时用用的话 一个 python 脚本也就搞定了

moult
    18

moult   2016-06-26 23:00:19 +08:00

腾讯云,后台有弹性 IP ,可以随时变 IP~~

如何自定义二级域名?

每个用户需要自己的二级域名,就像这样:

1 、 http://miya1201.tumblr.com/

2 、 http://ass-trals.tumblr.com/

而不是这样:

1 、 http://my.oschina.net/u/2300487

1 、 http://my.oschina.net/u/2819278

当用户填写自己的用户名,提交后,就自动生成二级域名,如何实现呢?

使用的 Apache

10 条回复    2016-06-29 17:52:13 +08:00
abelyao
    1

abelyao   2016-06-28 12:19:08 +08:00 via iPhone   ❤️ 1

泛域名解析,服务器收到请求之后把 host 作为业务逻辑的参数
ango
    2

ango   2016-06-28 12:20:41 +08:00   ❤️ 1

1 、*.domain.com
2 、 server rewrite

猜测应该是这样吧

Marfal
    3

Marfal   2016-06-28 12:28:15 +08:00   ❤️ 2

无形飙车,*为致命
hlg002
    4

hlg002   2016-06-28 12:29:36 +08:00

RewriteEngine on
RewriteRule ^aaa.$ /www.domain.com/$1
(╭☞•́ω•̀)╭☞ 这样么
ss098
    5

ss098   2016-06-28 12:41:45 +08:00   ❤️ 1

你提到的 Rewrite 是一种方案,比如有如下链接:

example.com/home/username

你可以使用 Rewrite 规则匹配 username.example.com 转发到如上链接,具体实现就不写了,你写的思路是正确的。

也可以在程序里匹配 username.example.com 。

Sasasu
    6

Sasasu   2016-06-28 13:30:32 +08:00 via Android

我没做过业务,但域名解析商一般是能提供 sdk 的….
icybee
    7

icybee   2016-06-28 13:56:13 +08:00

参考这篇文章的动态二级域名解析部分 http://icybee.cn/article/57.html
zacharyjia
    8

zacharyjia   2016-06-28 14:47:27 +08:00

泛域名解析是肯定需要的,然后在服务器上处理的话,有些框架提供相应的判断。
比如 Laravel 在路由的部分就提供了 domain 字段,可以在里面进行相应的定义,并且可以拿出来当做参数使用。
参考下面这个:
http://www.jianshu.com/p/e10f7fd84b08
hlg002
    9

hlg002   2016-06-29 17:04:38 +08:00

@abelyao
@ango
@ss098
@zacharyjia

功能实现了。但是。。。。 URL 自动跳转了啊
输入 http://miya1201.tumblr.com/ 地址栏 变成了 http://tumblr.com?name=miya1201

(╯°□°)╯︵ ┻━┻

hlg002
    10

hlg002   2016-06-29 17:52:13 +08:00

@abelyao 你这个不错,不需要 rewrite
%title插图%num

国内哪里有 ipv6 的服务器,校园网有 ipv6 想搭建代理

学校流量太贵,根本不够用,用过马上 6 ,延迟和网速都不稳定,想自己买个 ipv6 的服务器搭建代理,可是搜一顿没有,手头上只有一个搬瓦工 有个 ipv6 , fq 倒是方便了,延迟不忍直视 顺便加一条,手上资金有限,尽量便宜点的

IPV6 搬瓦工 延迟 服务器23 条回复 • 2017-11-30 17:15:15 +08:00
Slienc7 1
Slienc7 2016-03-27 20:22:26 +08:00 via Android
景安
binbinyouliiii 2
binbinyouliiii 2016-03-27 20:34:45 +08:00
@xgowex 这个带宽*高 3m 啊,有点小啊
watermeter 3
watermeter 2016-03-27 20:38:44 +08:00 via Android
6 年级+阿里云 也有现成的
lsylsy2 4
lsylsy2 2016-03-27 20:39:35 +08:00
国内不要想了……要么就是 6 年级
zpole 5
zpole 2016-03-27 22:43:33 +08:00 via iPad
真的不考虑境外吗, ipv6 一把把送的 lol
silenceseu 6
silenceseu 2016-03-27 23:55:30 +08:00 via iPhone
买个香港的 vps 吧
yexm0 7
yexm0 2016-03-27 23:57:56 +08:00 via Android
或者买香港 sl 的咯,走 hkix 的延迟应该很不错,至于国内的就别想了。价格昂贵,带宽又小。
Bryan0Z 8
Bryan0Z 2016-03-28 00:16:10 +08:00 via Android
Conoha 有 ipv6 ,教育网挺快
我自己用的 DO
这两个都是送 16 个 ipv6 地址,够你玩很久了
lincanbin 9
lincanbin 2016-03-28 07:48:33 +08:00
还有流量计费的学校,真黑。

为什么不找附近不限流量的学校的朋友,让他们给你开个 IPv6 代理呢?
binbinyouliiii 10
binbinyouliiii 2016-03-28 10:37:10 +08:00
@lincanbin 据我所知很多学校都是限流量的,学校就是坑,自己拉网线都不行,还 tm 是移动的网,坑死了,朋友也没有懂这个的,就算有总归还是在自己手里操作方便
sean10 11
sean10 2016-03-28 11:00:42 +08:00 via iPhone
@binbinyouliiii 走 do 吧,我走 do 的 ipv6 看看 B 站视频速度还是不错的
nyanyh 12
nyanyh 2016-03-28 16:12:04 +08:00
@sean10 B 站的地区限制怎么办?
sean10 13
sean10 2016-03-28 17:30:59 +08:00 via iPad
@nyanyh 要看版权限制的就暂时关代理吧,新番之类就那么多部,学校的免费流量限额一般足够了。而且有些番 YouTube 上有。。
nyanyh 14
nyanyh 2016-03-28 19:22:14 +08:00
@sean10 wat 贵校 IPv6 还限制流量吗?
sean10 15
sean10 2016-03-28 20:52:26 +08:00 via iPhone
@nyanyh 我是指用 ipv4 的免费流量看国内才能看的那些地区受限的
FishTorres 16
FishTorres 2016-04-01 23:49:42 +08:00
@Bryan0Z v6 走美国吗 v4 电信如何
Bryan0Z 17
Bryan0Z 2016-04-02 01:45:09 +08:00 via Android
@FishTorres 电信 ipv4 啊,找走 CN2 的都可以,我是觉得美国机房更好(便宜),毕竟翻出去主要还是逛逛 fb 油管什么的,日本新加坡机房虽然 ping 低,但是 100 和 180 在浏览网页,看视频时感觉不出区别
chenxi6934 18
chenxi6934 2016-04-29 16:25:39 +08:00 via iPhone
@watermeter 是用阿里云配置六年级让它支持 ipv6 吗
watermeter 19
watermeter 2016-04-29 16:29:57 +08:00 via Android
@chenxi6934 可以这么弄
chenxi6934 20
chenxi6934 2016-04-29 18:31:05 +08:00
@watermeter 大大!但是 6 年级有 LINUX 版本吗 我应该怎么在 VPS 下配置 6 年级呢-。-
watermeter 21
watermeter 2016-04-29 19:37:47 +08:00 via Android
@chenxi6934 6 年级就是个 open*
chenxi6934 22
chenxi6934 2016-04-30 01:01:13 +08:00 via iPhone
@watermeter 那我怎么能获得.o* 文件呢…
我看网站上也不放出 o* 啊…
gky99 23
gky99 2017-11-30 17:15:15 +08:00
@watermeter 六年级是正式名称是啥