Jump to content
新域网络技术论坛

All Activity

This stream auto-updates     

  1. Earlier
  2. package main import ( "./myfunc" //加载本项目包 "flag" //解析命令行参数 "fmt" "os" "strconv" ) //定义解析的命令行参数 var s = flag.String("s", "", "某某字符串") var b = flag.Bool("b", false, "布尔参数") func main() { //定义names变量 等同于 names := "World" var names = "World" //遍历命令行参数并输出 for idx, args := range os.Args { fmt.Println(strconv.Itoa(idx) + ":", args) } //解析命令行参数并赋值 flag.Parse() fmt.Println("-b:", *b) fmt.Println("-s:", *s) //未解析的参数 var params = flag.Args() fmt.Println(params) //如果有未解析的参数,访问 if len(params) > 0 { names = params[0] } fmt.Println("Hello " + names + "!") //多数据定义并赋值 var a, b = 2, 3 //省略var的方式定义,如果之前已经有此变量时会产生编译错误 c := 99 fmt.Printf("%d _++_+ %d, %x\n", a, b, &c) // & 取地址 * 取内容 fmt.Println(*&c) //调用其他包的函数 fmt.Println(myfunc.Demo("Hello", "=-=-=", "World!")) //字典定义以及遍历 dict := map[string] string {"One": "1111", "Two": "2222", "Three": "3333",} for k, v := range dict { fmt.Printf("%s: %s\n", k, v) } } /* 文件名及路径:myfunc/functions.go */ package myfunc func Demo(sstr ...string) string { result := "" //数组遍历方式 /*for i := 0; i < len(sstr); i ++ { result += " " + sstr[i] }*/ //通用遍历方式 数组、切片、字典通用 for _, v := range sstr { result += " " + v } return result }
  3. 继续优化python代码,添加请求模式(POST|GET),添加链接配置,直接通过参数可控制具体请求的链接。 # -*- Coding: UTF-8 -*- """ 自定义参数高并发压力测试工具 @author Jamers @since 2019.05.08 """ import time import sys import getopt import asyncio from aiohttp import ClientSession import json import re import codecs sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach()) url = "http://192.168.0.200/cli/asynctest.php" tasks = [] result = {} def usage(): print("usage: python " + sys.argv[0] + " -n 100 -c 500 -m post|get http://www.baidu.com") sys.exit() async def run(cid=0, obj=None): global cols if obj is None: obj = asyncio.Semaphore(cols) async with obj: async with ClientSession() as session: if method == 'get': resp = session.get(url, data={"id": cid}) else: resp = session.post(url, data={"id": cid}) async with resp as response: try: text = await response.text() j = json.loads(text) except json.JSONDecodeError: if -1 not in result: result[-1] = 0 result[-1] += 1 else: if j["code"] not in result: result[j["code"]] = 0 result[j["code"]] += 1 # print(j) if __name__ == "__main__": nums = 10 cols = 500 method = 'get' if len(sys.argv) > 1: opts, args = getopt.getopt(sys.argv[1:], "hn:c:m:") if len(args) > 0: reg = re.compile(r"^https?://[^/]{3,}\S*$", re.I) url = args.pop(0) if not reg.match(url): print("URL must be Illegal") usage() for op, value in opts: if op == "-h": usage() elif op == "-n": nums = int(value) elif op == '-c': cols = int(value) elif op == '-m': tmp = value.lower() if tmp in ['post', 'get', ]: method = tmp else: print("method only set to post or get") usage() loop = asyncio.get_event_loop() start_time = time.time() semaphore = asyncio.Semaphore(cols) tasks = [run(cid, semaphore) for cid in range(nums)] loop.run_until_complete(asyncio.wait(tasks)) loop.close() end_time = time.time() print(result) print("Loop Nums:", str(nums)) print("Start Time:", str(start_time)) print("End Time:", str(end_time)) print("Running Time:", str(end_time - start_time))
  4. 我在FREEBSD上测试过了,用参数 -n 10000 -c 10000 没问题,所以并发压力测试的时候尽量不要用windows,另外考虑带宽问题,尽量在内网走,基本不受带宽限制。 如果像高并发秒杀的时候,可以模拟各种情况了。甚至于分析最终秒杀成功的用户是否属于随机,保证算法的公平性。
  5. apache中有ab压力测试工具,但是无法自定义参数,并且无法分析最终结果,特写此文,共勉之。 我们先在服务端创建一个有10%概率成功的PHP脚本,由于高并发使用默认的随机数算法可能有些问题,所以采用了自定义的随机数种子算法。这里接收id用以区分请求顺序号。 $rate = 10; $id = isset($_REQUEST['id']) ? $_REQUEST['id'] : '0'; $seed = sRandSeed(); mt_srand($seed); if (mt_rand(1, 100) <= $rate) { $code = 0; $msg = 'success'; } else { $code = 1; $msg = 'busy'; } header('Content-type: application/json'); echo json_encode(['code' => $code, 'msg' => $msg, 'id' => $id, 'seed' => $seed,]); function sRandSeed() { $hash = md5(session_create_id()); $result = 0x003F; foreach (str_split($hash, 8) as $v) { $result ^= hexdec($v); } return $result & 0x7FFFFFFF; } 由于windows最大同时打开文件只能是512个,我这里限制最大并发数为500了,如果非windows可以适当增加此值,否则会报错,无法执行下去。由于高并发的时候,有可能http服务会报错,如果返回的值不是标准json串,设置此次请求为失效(code = -1),并统计各code的数量。 # -*- Coding: UTF-8 -*- import time import sys import getopt import asyncio from aiohttp import ClientSession import json import codecs sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach()) url = "http://192.168.0.200/cli/asynctest.php" tasks = [] result = {} async def run(cid=0, obj=None): global cols if obj is None: obj = asyncio.Semaphore(cols) async with obj: async with ClientSession() as session: async with session.post(url, data={"id": cid}) as response: try: text = await response.text() j = json.loads(text) except json.JSONDecodeError: if -1 not in result: result[-1] = 0 result[-1] += 1 else: if j["code"] not in result: result[j["code"]] = 0 result[j["code"]] += 1 # print(j) if __name__ == "__main__": nums = 10 cols = 500 if len(sys.argv) > 1: opts, args = getopt.getopt(sys.argv[1:], "hn:c:") for op, value in opts: if op == "-h": print("python " + sys.argv[0] + " -n 100 -c 500") sys.exit() elif op == "-n": nums = int(value) elif op == '-c': cols = int(value) loop = asyncio.get_event_loop() start_time = time.time() semaphore = asyncio.Semaphore(cols) tasks = [run(cid, semaphore) for cid in range(nums)] loop.run_until_complete(asyncio.wait(tasks)) loop.close() end_time = time.time() print(result) print("Loop Nums:", str(nums)) print("Start Time:", str(start_time)) print("End Time:", str(end_time)) print("Running Time:", str(end_time - start_time))
  6. 使用场景模拟,例如:登录过程中,有很多相关日志、积分或者某些活动参加部分解耦,将这些相关联模块采用观察者模式,用户登录时添加这些观察者,通知一次,观察者们会自动调用相关的方法处理。避免登录模块中掺杂过多的其他方面的代码。 /** * 事件产生类 * Class EventGenerator */ abstract class EventGenerator { private $ObServers = []; //增加观察者 public function add(ObServer $ObServer) { $this->ObServers[] = $ObServer; } //事件通知 public function notify($msg = '') { foreach ($this->ObServers as $ObServer) { $ObServer->update($msg); } } } /** * 观察者接口类 * Interface ObServer */ interface ObServer { public function update($event_info = null); } /** * 观察者1 */ class ObServer1 implements ObServer { public function update($event_info = null) { var_dump($event_info); echo "观察者1 收到执行通知 执行完毕!\n"; } } /** * 观察者1 */ class ObServer2 implements ObServer { public function update($event_info = null) { var_dump($event_info); echo "观察者2 收到执行通知 执行完毕!\n"; } } /** * 事件 * Class Event */ class Event extends EventGenerator { /** * 触发事件 */ public function trigger() { //通知观察者 $this->notify(mt_rand(1, 10)); } } //创建一个事件 $event = new Event(); //为事件增加旁观者 $event->add(new ObServer1()); $event->add(new ObServer2()); //执行事件 通知旁观者 $event->trigger(); sleep(1); $event->trigger();
  7. 继续学习: 痛苦的,连基本的数组操作也需要自己写过程,字符串操作之类也很麻烦,其他语言有大量的内置函数真的很好。如果没有一个好的封装库的话,肯定会很慢,真的! /** * 素数 */ private static void prime() { int num; System.out.print("请输入一个整数:"); try { Scanner sc = new Scanner(System.in); num = sc.nextInt(); if (num > 1) { boolean isPrime = true; for (int i = 2; i < Math.sqrt(num); i++) { if (num % i == 0) { isPrime = false; break; } } if (isPrime) { System.out.printf("%d 是素数\n", num); } else { System.out.printf("%d 不是素数\n", num); } } else { System.out.println("输入的数字必须大于1"); } } catch (Exception e) { System.out.println(e.toString()); } } /** * 水仙花数 */ private static void asphodel() { String str; int s1, s2, s3, count = 0; for (int i = 100; i < 1000; i++) { str = String.valueOf(i); s1 = Integer.parseInt(new String(new char[]{str.charAt(0)})); s2 = Integer.parseInt(new String(new char[]{str.charAt(1)})); s3 = Integer.parseInt(new String(new char[]{str.charAt(2)})); if (i == Math.pow(s1, 3) + Math.pow(s2, 3) + Math.pow(s3, 3)) { count ++; System.out.print(i + " "); } } System.out.printf("\n水仙花数共有 %d 个\n", count); } /** * 正则与时间 */ private static void regular() { String date; Date dt = new Date(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); date = format.format(dt); System.out.println(date); String p = "(\\d{4})-(\\d{2})-(\\d{2}) (\\d+):(\\d+):(\\d+)"; Pattern r = Pattern.compile(p); Matcher m = r.matcher(date); if (m.find()) { String[] ary = {}; for (int i = 0; i <= m.groupCount(); i++) { ary = pushArray(ary, m.group(i)); } Vardump.print(ary); } else { System.out.println("NO MATCH"); } } /** * 操蛋,连数组操作也要自己造轮子? * @param src * @param push * @return */ private static String[] pushArray(String[] src, String push) { String[] tempArray = new String[src.length + 1]; for (int i = 0;i < src.length; i++) { tempArray[i] = src[i]; } tempArray[src.length] = push; return tempArray; }
  8. 2019.04.13 学习内容: 1. Swap 变量返回问题 2. 字符串输入 3. 类似PHP中的魔法调用,用反射方式动态调用不同方法 import java.lang.reflect.*; import java.util.Scanner; import cn.lcfms.utils.*; public class Main { public static void main(String[] args) { String opt = ""; try { if (args.length > 0) { Vardump.print(args); opt = args[0].toLowerCase(); System.out.printf("Operate: %s \n", opt); } else { System.out.printf("Option is empty"); return; } } catch (Exception e) { System.out.println(e.toString()); } try { java.lang.Class[] empty_class = new java.lang.Class[]{}; java.lang.Object[] empty_object = new java.lang.Object[]{}; Method method = Main.class.getDeclaredMethod(opt, empty_class); method.setAccessible(true); method.invoke(null, empty_object); } catch (NoSuchMethodException e) { System.out.println(e.toString()); System.out.printf("Option '%s' is incorrect", opt); } catch (Exception e) { System.out.println(e.toString()); } } /** * 交换数值入口 */ private static void swap() { Integer a, b; a = 10; b = 20; System.out.printf("a = %d, b = %d\n", a, b); try { doSwap(a, b); } catch (Exception e) { System.out.println(e.toString()); } System.out.printf("a = %d, b = %d\n", a, b); } /** * 交换数值处理过程 * @param a * @param b * @throws Exception */ private static void doSwap(Integer a, Integer b) throws Exception { // 请在这里实现交换过程 int c = a; Integer cInteger = new Integer(c); Class<? extends Integer> aClass = a.getClass(); Field avalue = aClass.getDeclaredField("value"); avalue.setAccessible(true); avalue.set(a, b); Class<? extends Integer> bClass = b.getClass(); Field bvalue = bClass.getDeclaredField("value"); bvalue.setAccessible(true); bvalue.set(b, cInteger); } /** * 输入字符串 */ private static void input() { System.out.print("请输入你的字符串:"); Scanner s = new Scanner(System.in); String val = s.nextLine(); String outstr = "你输入的字符串为空"; if (val.length() > 0) { outstr = String.format("你输入的字符串为:%s,长度为:%d", val, val.length()); } System.out.println(outstr); } private static void rightnum() { System.out.println("run rightnum"); } }
  9. 这个问题原来是C++的版本,目前在学习Java中,问题就用Java描述吧。 看代码:将变量a 和 b的值交换后输出。当然实际情况下,肯定不允许这样的情况发生,如果可以传指参的话,直接使用指参就可以了,比如PHP里可以直接使用 function doSwap(&$a, &$b) {...} 就可以了,我查了一下JAVA是没有指参的,所以不能这么处理。代码中还有部分不是太理解,逻辑是理解了,等后续再看吧。 public class Main { public static void main(String[] args) { Integer a, b; a = 1; b = 2; System.out.printf("a = %d, b = %d\n", a, b); try { doSwap(a, b); } catch (Exception e) { System.out.println(e.toString()); } System.out.printf("a = %d, b = %d\n", a, b); } private static void doSwap(Integer a, Integer b) throws Exception { // 请在这里实现交换过程 } } 我这里先给出一个PHP版本的解法,不使用Class的情况是可以实现的,如果限制在Class环境中,暂时还没想到实现方式,PHP中没有内存操作的概。: $a = 10; $b = 20; echo "a:{$a} b:{$b}\n"; doSwap($a, $b); echo "a:{$a} b:{$b}\n"; function doSwap($a, $b) { /* 请实现交换两个变量 预期结果: a:1 b:2 a:2 b:1 */ global $a, $b; $c = $a; $a = $b; $b = $c; } 看一下JAVA的实现方式,你没看错,就这个操作需要这么长的代码: import java.lang.reflect.Field; public class Main { public static void main(String[] args) { Integer a, b; a = 1; b = 2; System.out.printf("a = %d, b = %d\n", a, b); try { doSwap(a, b); } catch (Exception e) { System.out.println(e.toString()); } System.out.printf("a = %d, b = %d\n", a, b); } private static void doSwap(Integer a, Integer b) throws java.lang.Exception { // 请在这里实现交换过程 int c = a; Integer cInteger = new Integer(c); Class<? extends Integer> aClass = a.getClass(); Field avalue = aClass.getDeclaredField("value"); avalue.setAccessible(true); avalue.set(a, b); Class<? extends Integer> bClass = b.getClass(); Field bvalue = bClass.getDeclaredField("value"); bvalue.setAccessible(true); bvalue.set(b, cInteger); } }
  10. 从PHP5.3开始phar模块已经默认编译在里面了,直接使用就可以了。 使用前需要把php.ini中的只读权限去掉, [Phar] ; http://php.net/phar.readonly ;phar.readonly = On phar.readonly = Off 然后新建一个PHP文件 if (class_exists('\Phar')) { $phar = new \Phar('demo.phar', 0, 'demo.phar'); $phar->buildFromDirectory(__DIR__ . '/a1/'); $phar->setStub($phar->createDefaultStub('demo.php', 'index.php')); $phar->compressFiles(Phar::GZ); } else { exit('no Phar module'); } 然后运行一下这个新的文件,指定目录下的所有文件(包括其他资源文件,是所有文件)都会被打包到phar文件中,运行时这些文件都可以直接被PHP代码调用 。如果没有错误的话,当前目录会产生一个指定的phar文件。然后就可以随便把它放到哪个目录下调用了。
  11. 在linux环境下,可以直接使用 composer install这样的操作,但是在windows里不能这么调用,必须使用 x:\php\php.exe x:\...\composer.phar install这样的操作方式,是不是感觉到太麻烦了?用这个脚本吧。 把这个文件composer.bat和composer.phar放在同一个目录下,然后设置一下自动搜索PATH,包含PHP的路径以及新增的这个目录(可以同时放到同一个目录下)。 @echo off php.exe %~dp0composer.phar %1 %2 %3 %4 %5 %6 %7 %8 %9 然后你就可以在命令行下的任何目录直接调用composer install之类的操作了。
  12. $where 使用示例: db.test.find({ "detail.test": {$nin:[null],$exists: true}, $where: function() { var ret = false; for(var curr in this.detail.test) { //print(this.detail.test[curr].nums); if (this.detail.test[curr].nums >= 100) { ret = true; break; } } return ret; } }); 以上仅为演示使用$where的方式,上面的功能推荐用子元素匹配处理,上面的效率太低了 db.test.find({ 'detail.test': { '$elemMatch': {'nums': {'$gte': 100}} }, } 查看print输出日志需要到服务器上直接查看日志,不推荐打开日志 tail -f /var/db/mongodb/mongod.log
  13. 试想一个场景: 自己Push了一个Commit后,后续有其他人也相继Push了相应的代码到Git库里,结果你发现自己的代码里的敏感信息,这时候怎么处理? 以下是测试过的处理方式: 进入git bash界面,到指定目录 git log 找到自己提交的前一个commit的hash值 git rebase -i hash 把自己的 pick own_hash 改成 drop own_hash 保存退出 git push origin HEAD --force 然后就一切正常啦 git log 查看一下
  14. 顺便把安装方式也一并添加一下吧。 报错如下: Warning: Invalid argument supplied for foreach() in Command.php on line 249 Warning: Invalid argument supplied for foreach() in /usr/local/share/pear/PEAR/Command.php on line 249 curl -O http://pear.php.net/go-pear.phar php go-pear.phar 一般安装在: /usr/local/bin/pecl ee `which pecl` 到最后一行,把-n 去掉就可以了。
  15. 啥也不说了,看代码片断 <a :href="['/demo.html?id='+item.id]" v-if="item.id">保单</a>
  16. 代理,我要代理 cd /usr/ports/www/squid make install clean #要身份验证,把mysql模块选上 cd /usr/ports/databases/p5-DBD-mysql/ make install clean # # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS # visible_hostname localhost auth_param basic program /usr/local/libexec/squid/basic_db_auth \ --dsn "DBI:mysql:host=localhost;port=3306;database=squid" \ --user squid --password squid --plaintext --persist auth_param basic children 5 auth_param basic realm Web-Proxy auth_param basic credentialsttl 1 minute auth_param basic casesensitive off acl db-auth proxy_auth REQUIRED http_access allow db-auth #http_port 3128 https_port 443 cert=/etc/ssl/squid.crt key=/etc/ssl/squid.key request_header_access Via deny all request_header_access X-Forwarded-For deny all request_header_access All allow all reply_header_access Server deny all reply_header_access X-Cache deny all reply_header_access X-Cache-Lookup deny all reply_header_access Warning deny all reply_header_access Expires deny all reply_header_access Cache-Control deny all reply_header_access age deny all #证书最好用正式签发的,因为访问代理服务器的时候需要使用与证书一致的域名进行访问 cd /etc/ssl openssl req -new -sha256 -keyout squid.key -nodes -x509 -days 3650 -out squid.crt openssl req -new -sha512 > squid.csr 密码:qqbx.cn openssl rsa -in privkey.pem -out squid.key openssl x509 -in squid.csr -out squid.crt -req -signkey squid.key -days 3650
  17. 很多情况下,用户频繁请求文件,会带走很多流量,其实有的时候根本没必要请求,怎么办呢?通过rewrite把所有的请求集中管理起来,判断有没有缓存,没缓存强制设置缓存,另外检查本地修改时间,如果已经修改直接更新,就是不知道上传到服务器上去的文件修改时间会不会一起改变,待测试! /* RewriteEngine on #RewriteBase /Test/ RewriteCond %{REQUEST_FILENAME} ^.*?\.(css|js|jpg|png)$ RewriteRule ^(.*)$ p304.php/$1 [QSA,PT,L] */ //静态文件尝试使用304方式优化 //缓存时间10年 $cache_time = 315360000; $root = $_SERVER['DOCUMENT_ROOT']; $file = $_SERVER['REQUEST_URI']; if (isset($_SERVER['REDIRECT_URL'])) { $file = $_SERVER['REDIRECT_URL']; }else{ $f = explode('?',$file); $file = $f[0]; } if (file_exists($root.$file)) { $is304 = false; if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) { $lt = strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]); $ft = filemtime($root.$file); if ($ft <= $lt) $is304 = true; } if ($is304) { header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified'); header("Cache-Control: max-age=$cache_time"); }else{ header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT"); header("Expires: " . gmdate("D, d M Y H:i:s", time() + $cache_time) . " GMT"); header("Cache-Control: max-age=$cache_time"); echo(file_get_contents($root . $file)); } }else{ header($_SERVER["SERVER_PROTOCOL"].' 404 Not Found'); }
  18. 使用FREEBSD的时候,使用SSH方式进行git操作的时候就经常30秒左右才有反应。经过ssh -v ip分析一直Dnslookup时候等回应,默认超时时间应该是30秒,所以就在这个环节等待30秒后继续处理后续动作,所以就慢了。 找到原因了,就去处理吧,首先,我们连接git服务器的时候是作为客户端的,所以sshd_config是不需要处理的。 ee /etc/ssh/ssh_config #把下列参数设置上就OK了 VerifyHostKeyDNS no 这个参数就是说不较验服务器DNS,设置完成后再去git操作时就快如闪电了。
  19. CI_ENV设置用以切换不同的配置文件。 apache httpd.conf下面添加,可选参数:development,testing,production <IfModule env_module> SetEnv CI_ENV development </IfModule>
  20. 今天把codeigniter升级到3.1.8,所有配置文件都看过了,就是使用 xxxx.xx/index.php/welcome 直接显示404,然后打印$_SERVER变量中发现居然没有PATH_INFO,然后开始漫长的搜索。 最后处理结果: 在apache的配置文件中目录配置中,添加下列语句: AcceptPathInfo On 然后重启Apache,就可以了。。唉。。。
  1. Load more activity
×
×
  • Create New...