最近花了一些时间,看了一下OpenResty的东西,感觉用来做API网关的确很赞:
https://github.com/neohope/NeoDemosOpenResty
官网:
https://openresty.org/cn/
Learn and share.
最近花了一些时间,看了一下OpenResty的东西,感觉用来做API网关的确很赞:
https://github.com/neohope/NeoDemosOpenResty
官网:
https://openresty.org/cn/
蓝牙设备自动唤醒功能有时候很有用,有时候很鸡肋。
有一次把笔记本休眠,放到包里,结果被蓝牙鼠标重新唤醒了Windows,导致整个电脑暴热,还好电量耗尽
于是就想禁用蓝牙唤醒:
# 查询设备 powercfg -a powercfg /devicequery wake_armed powercfg /devicequery wake_programmable # 禁用设备 powercfg /devicedisablewake "HID-compliant mouse (003)" # 启用设备自动唤醒 powercfg /deviceenableawake "HID-compliant mouse (003)"
在Windows平台上,也可以通过Custom Protocol实现Chrome打开EXE进程,调用CS程序
1、通过注册表,实现单一用户支持Custom Protocol
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\SOFTWARE\Classes\MyProtocol] "URL Protocol"="" @="MyProtocol" [HKEY_CURRENT_USER\SOFTWARE\Classes\MyProtocol\DefaultIcon] @="FULL_PATH_TO_MYAPP\\MYAPP.exe.exe, 1" [HKEY_CURRENT_USER\SOFTWARE\Classes\MyProtocol\Shell] [HKEY_CURRENT_USER\SOFTWARE\Classes\MyProtocol\Shell\Open] [HKEY_CURRENT_USER\SOFTWARE\Classes\MyProtocol\Shell\Open\command] @="\"FULL_PATH_TO_MYAPP\\MYAPP.exe\" \"%1\""
2、通过注册表,让全体用户支持Custom Protocol,需要管理员权限
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\Software\Classes\MyProtocol] "URL Protocol"="" @="MyProtocol" [HKEY_CURRENT_USER\SOFTWARE\Classes\MyProtocol\DefaultIcon] @="FULL_PATH_TO_MYAPP\\MYAPP.exe.exe, 1" [HKEY_CURRENT_USER\SOFTWARE\Classes\MyProtocol\Shell] [HKEY_CURRENT_USER\SOFTWARE\Classes\MyProtocol\Shell\Open] [HKEY_CURRENT_USER\SOFTWARE\Classes\MyProtocol\Shell\Open\command] @="\"FULL_PATH_TO_MYAPP\\MYAPP.exe\" \"%1\""
1、确保cdt01可以ssh联通cdt02和cdt03
#这个userid与可以无密码使用sudo的userid相同 ssh -l userid cdh02 ssh -l userid cdh03
2、浏览器访问(以后都是界面了)
http://172.16.172.101:7180
用户名:admin
密码:admin
3、根据引导界面,新建Cluster
将172.16.172.101-172.16.172.103都安装好cloudera-manager-agent
4、根据引导界面,选用需要的软件进行安装
安装时,注意合理分配角色,也就是合理分配内存资源
5、依次安装
hdfs
zookeeper
hbase
yarn
hive
spark
6、安装完毕
PS:
1、如果出现找不到jdbc driver的情况
sudo apt-get install libmysql-java
1、cdt01安装
#添加cloudera仓库 wget https://archive.cloudera.com/cm6/6.3.0/ubuntu1804/apt/archive.key sudo apt-key add archive.key wget https://archive.cloudera.com/cm6/6.3.0/ubuntu1804/apt/cloudera-manager.list sudo mv cloudera-manager.list /etc/apt/sources.list.d/ #更新软件清单 sudo apt-get update #安装jdk8 sudo apt-get install openjdk-8-jdk #安装cloudera sudo apt-get install cloudera-manager-daemons cloudera-manager-agent cloudera-manager-server
2、安装及配置mysql
2.1、安装mysql
sudo apt-get install mysql-server mysql-client libmysqlclient-dev libmysql-java
2.2、停止mysql
sudo service mysql stop
2.3、删除不需要的文件
sudo rm /var/lib/mysql/ib_logfile0 sudo rm /var/lib/mysql/ib_logfile1
2.4、修改配置文件
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf #修改或添加以下信息 [mysqld] transaction-isolation = READ-COMMITTED max_allowed_packet = 32M max_connections = 300 innodb_flush_method = O_DIRECT
2.5、启动mysql
sudo service mysql start
2.6、初始化mysql
sudo mysql_secure_installation
3、创建数据库并授权
sudo mysql -uroot -p
-- 创建数据库 -- Cloudera Manager Server CREATE DATABASE scm DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; -- Activity Monitor CREATE DATABASE amon DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; -- Reports Manager CREATE DATABASE rman DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; -- Hue CREATE DATABASE hue DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; -- Hive Metastore Server CREATE DATABASE hive DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; -- Sentry Server CREATE DATABASE sentry DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; -- Cloudera Navigator Audit Server CREATE DATABASE nav DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; -- Cloudera Navigator Metadata Server CREATE DATABASE navms DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; -- Oozie CREATE DATABASE oozie DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; #创建用户并授权 GRANT ALL ON scm.* TO 'scm'@'%' IDENTIFIED BY 'scm123456'; GRANT ALL ON amon.* TO 'amon'@'%' IDENTIFIED BY 'amon123456'; GRANT ALL ON rman.* TO 'rman'@'%' IDENTIFIED BY 'rman123456'; GRANT ALL ON hue.* TO 'hue'@'%' IDENTIFIED BY 'hue123456'; GRANT ALL ON hive.* TO 'hive'@'%' IDENTIFIED BY 'hive123456'; GRANT ALL ON sentry.* TO 'sentry'@'%' IDENTIFIED BY 'sentry123456'; GRANT ALL ON nav.* TO 'nav'@'%' IDENTIFIED BY 'nav123456'; GRANT ALL ON navms.* TO 'navms'@'%' IDENTIFIED BY 'navms123456'; GRANT ALL ON oozie.* TO 'oozie'@'%' IDENTIFIED BY 'oozie123456';
4、初始化数据库
sudo /opt/cloudera/cm/schema/scm_prepare_database.sh mysql scm scm scm123456 sudo /opt/cloudera/cm/schema/scm_prepare_database.sh mysql amon amon amon123456 sudo /opt/cloudera/cm/schema/scm_prepare_database.sh mysql rman rman rman123456 sudo /opt/cloudera/cm/schema/scm_prepare_database.sh mysql hue hue hue123456 sudo /opt/cloudera/cm/schema/scm_prepare_database.sh mysql hive hive hive123456 sudo /opt/cloudera/cm/schema/scm_prepare_database.sh mysql sentry sentry sentry123456 sudo /opt/cloudera/cm/schema/scm_prepare_database.sh mysql nav nav nav123456 sudo /opt/cloudera/cm/schema/scm_prepare_database.sh mysql navms navms navms123456 sudo /opt/cloudera/cm/schema/scm_prepare_database.sh mysql oozie oozie oozie123456
5、启动
#启动cloudera-scm-server sudo systemctl start cloudera-scm-server #查看启动日志,等待Jetty启动完成 sudo tail -f /var/log/cloudera-scm-server/cloudera-scm-server.log
6、启动
浏览器访问
http://172.16.172.101:7180
用户名:admin
密码:admin
1、环境准备
VirtualBox 6 Ubuntu 18 Cloudera CDH 6.3
2、虚拟机安装Ubuntu18,配置为
1CPU
4G内存
300G硬盘
两块网卡,一块为HostOnly,一块为NAT
3、将虚拟机克隆为三份
如果是手工拷贝,记得修改硬盘UUID、虚拟机UUID、网卡硬件ID
4、设置IP地址、hostname及hosts文件
| 机器名 | HostOnly IP |
| cdh01 | 172.16.172.101 |
| cdh02 | 172.16.172.102 |
| cdh03 | 172.16.172.103 |
5、允许无密码使用sudo,至少修改cdh02和cdh03
#edit /etc/sudoers userid ALL=(ALL:ALL) NOPASSWD: ALL
这个问题,就要去看一下OpenJDK的源码了:
//在Proxy类里中:
//constructorParams的定义如下:
private static final Class<?>[] constructorParams = { InvocationHandler.class };
//newProxyInstance无限精简之后就是:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
throws IllegalArgumentException {
//通过ProxyClassFactory调用ProxyGenerator生成了代理类
Class<?> cl = getProxyClass0(loader, interfaces);
//找到参数为InvocationHandler.class的构造函数
final Constructor<?> cons = cl.getConstructor(constructorParams);
//创建代理类实例
return cons.newInstance(new Object[]{h});
}
//在ProxyGenerator类中:
public static byte[] generateProxyClass(final String name,Class<?>[] interfaces, int accessFlags)){}
private byte[] generateClassFile() {}
//上面两个方法,做的就是:
//将接口全部进行代理
//并生成其他需要的方法,比如上面用到的构造函数、toString、equals、hashCode等
//生成对应的字节码
//其实这也就说明了,为何JDK的动态代理,必须需要至少一个接口
一、Jetty的ScopedHandler的doStart方法,最后一步是将线程私有变量__outerScope设置成null,为什么需要这样做呢?
protected void doStart() throws Exception
{
try{
_outerScope=__outerScope.get();
if (_outerScope==null){
//本次处理的第一个scope handler
//告知后续scope handler,_outerScope选我
__outerScope.set(this);
}
super.doStart();
_nextScope= getChildHandlerByClass(ScopedHandler.class);
}
finally
{
if (_outerScope==null){
//本次处理结束
//为了下次同一个线程处理是,
//还能正常的设置第一个scope handler
//必须把threadlocal变量设为null
__outerScope.set(null);
}
}
}
二、Jetty中,ScopedHandler中nextHandle调用顺序是如何的?
//此外,这一节里有一个non scoped handler X,一开始没太看懂调阅顺序。
//后来发现是这样的:
public final void nextHandle(String target...)...
{
if (_nextScope!=null && _nextScope==_handler){
//上面条件可以保证下一个handler是scope handler
_nextScope.doHandle(target,baseRequest,request, response);
}
else if (_handler!=null){
//non scpoe handler调用下一个handler的
super.handle(target,baseRequest,request,response);
}
}
感觉类成员的命名不太合适,
比如__outerScope和_outerScope
比如_handler其实一直指向的是下一个handler,是不是该为_nextHandler更好一些?
小米电视越来越慢,就想多删除一些应用:
注意:预装应用删除后,除了升级系统,并没有好的恢复方法,使用命令需谨慎
#首先在小米电视上打开远程调试,让ADB可以远程连接 开启开发者模式:设置-》关于-》产品型号-》遥控连续按5下OK键 设备安全设置:设置-》账号与安全-》允许安装未知来源的应用-》允许ADB调试 查看网络IP:设置-》网络-》找到电视使用的局域网IP #远程连接小米电视 adb connect IP #显示已连接设备 adb devices #安装APK包 adb install -r PATH_TO_APK/MyAPK.apk #列出已安装的包 adb shell pm list packages #删除具体应用(不同版本包名有差异) 应用商店 adb shell pm uninstall com.xiaomi.mitv.appstore 小米商城 adb shell pm uninstall com.xiaomi.mitv.shop 小米支付 adb shell pm uninstall com.xiaomi.mitv.payment 小米钱包 adb shell pm uninstall com.mipay.wallet.tv 天气 adb shell pm uninstall com.xiaomi.tweather 时尚画报 adb shell pm uninstall com.xiaomi.tv.gallery 相册 adb shell pm uninstall com.mitv.gallery 照片屏幕保护程序 adb shell pm uninstall com.android.dreams.phototable 游戏中心 adb shell pm uninstall com.xiaomi.mibox.gamecenter 日历 adb shell pm uninstall com.xiaomi.mitv.calendar 提醒 adb shell pm uninstall com.mitv.alarmcenter 用户手册 adb shell pm uninstall com.xiaomi.mitv.handbook 热点新闻 adb shell pm uninstall com.duokan.videodaily 新闻 adb shell pm uninstall com.xiaomi.mitvnews 米家 adb shell pm uninstall com.xiaomi.smarthome.tv 小米盒子设置 adb shell pm uninstall com.xiaomi.mitv.settings #重启设备 adb shell reboot adb shell reboot -p
对比一下,Servlet容器、Spring容器和SpringMVC容器。
Servlet容器,是用于管理Servlet生命周期的。
Spring容器,是用于管理Spring Bean生命周期的。
SpringMVC容器,适用于管理SpringMVC Bean生命周期的。
Tomcat/Jetty启动,对于每个WebApp,依次进行初始化工作:
1、对每个WebApp,都有一个WebApp ClassLoader,和一个ServletContext
2、ServletContext启动时,会扫描web.xml配置文件,找到Filter、Listener和Servlet配置
3、如果Listener中配有spring的ContextLoaderListener
3.1、ContextLoaderListener就会收到webapp的各种状态信息。
3.3、在ServletContext初始化时,ContextLoaderListener也就会将Spring IOC容器进行初始化,管理Spring相关的Bean。
3.4、ContextLoaderListener会将Spring IOC容器存放到ServletContext中
4、如果Servlet中配有SpringMVC的DispatcherServlet
4.1、DispatcherServlet初始化时(其一次请求到达)。
4.2、其中,DispatcherServlet会初始化自己的SpringMVC容器,用来管理Spring MVC相关的Bean。
4.3、SpringMVC容器可以通过ServletContext获取Spring容器,并将Spring容器设置为自己的根容器。而子容器可以访问父容器,从而在Controller里可以访问Service对象,但是在Service里不可以访问Controller对象。
4.2、初始化完毕后,DispatcherServlet开始处理MVC中的请求映射关系。
我面试的时候,有段时间经常会问一个很坑问题,Servlet默认是单例模式的,Spring的Bean默认是单例模式的,那Spring MVC是如何处理并发请求的呢?