Android Studio 2.0+发布APK出现ExternalSystemException: String index out of range: -123错误

前阵子Android Studio 2.0正式版发布了,很高兴的就升到了最新版本。 一编译就出现400多个错误提示,Gradle2.0编译速度也让人泪奔,哎,可能是技术太渣不懂那些配置,晚晚加班也没时间学习,还好debug方式编译正常运行 今天老大叫发布APK,使用Android Studio2.0 release APK 时出现ExternalSystemException: String index out of range: -123错误提示, 搞了一个晚上终于解决了,记忆不好,在这里记录一下,怕以后出现类似问题忘记怎么解决。 解决方法: 在主项目build.gradle的android标签里加上 lintOptions { checkReleaseBuilds **false ** *// Or, if you prefer, you can continue to check for errors in release builds, ** // but continue the build even when errors are found: * abortOnError **false **} 如图: ![](http://img.blog.csdn.net/20160423152939548?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 转自:http://blog.csdn.net/jia__/article/details/51226475

2016年9月22日 · 1 分钟 · 天边的星星

WebSocket的C++服务器端实现

由于需要在项目中增加Websocket协议,与客户端进行通信,不想使用开源的库,比如WebSocketPP,就自己根据WebSocket协议实现一套函数,完全使用C++实现。 代码已经实现,放在个人github上面,地址:https://github.com/jice1001/websocket.git。下面进行解释说明: 一、原理 Websocket协议解析,已经在前面博客里面详细讲解过,可以参考博客http://www.cnblogs.com/jice1990/p/5435419.html,这里就不详细细说。 服务器端实现就是使用TCP协议,使用传统的socket流程进行绑定监听,使用epoll控制多路并发,收到Websocket握手包时候进行握手处理,握手成功便可进行数据收发。 二、实现 1、服务器监听 该部分使用的是TCP socket流程,首先是通过socket函数建立socket,通过bind函数绑定到某个端口,本例使用的是9000,然后通过listen函数开启监听,代码如下: ![复制代码](http://common.cnblogs.com/images/copycode.gif) listenfd_ = socket(AF_INET, SOCK_STREAM, 0); if(listenfd_ == -1){ DEBUG_LOG("创建套接字失败!"); return -1; } struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(PORT); if(-1 == bind(listenfd_, (struct sockaddr *)(&server_addr), sizeof(server_addr))){ DEBUG_LOG("绑定套接字失败!"); return -1; } if(-1 == listen(listenfd_, 5)){ DEBUG_LOG("监听失败!"); return -1; } ![复制代码](http://common.cnblogs.com/images/copycode.gif) 2、epoll控制多路并发 ...

2016年9月11日 · 4 分钟 · 天边的星星

opencv提取轮廓与抠图

自然图像抠图/视频抠像技术梳理(image matting, video matting)-计算机视视觉专题1 http://download.csdn.net/detail/jlwyc/4676516 学习opencv ,图像分割中分水岭算法的感性认识及cvWatershed例子 OpenCV学习:轮廓 OpenCV函数cvFindContours 提取轮廓两种方法及绘制轮廓中最大等级分析 【OpenCV入门指南】第三篇Canny边缘检测 【OpenCV入门指南】第四篇 图像的二值化 【OpenCV入门指南】第五篇 轮廓检测 上 【OpenCV入门指南】第六篇 轮廓检测 下 在图像中寻找轮廓 OPENCV中cvFindContours函数说明 给轮廓画出矩形和圆形边界 (转)提取不规则图像 OpenCv的连通域操作 opencv图像剪切,保存局部,图像抠取 OpenCV中Mat类的图像如何设置ROI OpenCV中图像及子图像ROI之间的复制 OpenCV2 图像叠加 给照片加水印 转自:http://blog.csdn.net/xdonx/article/details/21557625

2016年9月11日 · 1 分钟 · 天边的星星

linux shell中 if else以及大于、小于、等于逻辑表达式介绍

比如比较字符串、判断文件是否存在及是否可读等,通常用”[]”来表示条件测试。 注意:这里的空格很重要。要确保方括号的空格。笔者就曾因为空格缺少或位置不对,而浪费好多宝贵的时间。 if ….; then …. elif ….; then …. else …. fi [ -f “somefile” ] :判断是否是一个文件 [ -x “/bin/ls” ] :判断/bin/ls是否存在并有可执行权限 [ -n “var” ] :判断var变量是否有值 [ “a” = “b” ] :判断a和b是否相等 -r file 用户可读为真 -w file 用户可写为真 -x file 用户可执行为真 -f file 文件为正规文件为真 -d file 文件为目录为真 -c file 文件为字符特殊文件为真 -b file 文件为块特殊文件为真 -s file 文件大小非0时为真 -t file 当文件描述符(默认为1)指定的设备为终端时为真 ** 字符串判断** str1 = str2 当两个串有相同内容、长度时为真 str1 != str2 当串str1和str2不等时为真 -n str1 当串的长度大于0时为真(串非空) -z str1 当串的长度为0时为真(空串) str1 当串str1为非空时为真 ...

2016年9月5日 · 7 分钟 · 天边的星星

android Shape只显示指定边框用法

<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- focused --> <item android:drawable="@drawable/orderboard_detail_tab_middle_selected" android:state_checked="true" /> <item android:drawable="@drawable/orderboard_detail_tab_middle_selected" android:state_selected="true" /> <!-- default --> <item > <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:left="-1dp" android:right="-1dp" > <shape android:shape="rectangle"> <solid android:color="@color/text_color_white" /> <stroke android:width="1dp" android:color="@color/text_color_blue" /> <padding android:left="0dp" android:right="0dp" /> <corners android:radius="0dp"/> </shape> </item> </layer-list> </item> </selector> 上面执行的结果:只画上下线 [![QQ20160830-0@2x](http://www.etongwl.com/images/2016/08/QQ20160830-0@2x-300x289.png)](http://www.etongwl.com/images/2016/08/QQ20160830-0@2x.png)

2016年8月30日 · 1 分钟 · 天边的星星

Android Toast花式使用

![](http://upload-images.jianshu.io/upload_images/828721-e0fc168c7e6ce054.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 之前写过一篇没时间解释了,快使用Snackbar!——Android Snackbar花式使用指南。Toast的自定义使用原理与其类似。 1.Toast源码分析 老规矩,我们先去看Toast的源码。 Toast有两种显示布局方式,一种最常见调用Toast.makeText(),看源码是这样写的 `<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Toast <span class="hljs-title">makeText</span>(<span class="hljs-params">Context context, CharSequence text, @Duration <span class="hljs-keyword">int</span> duration</span>) </span>{ Toast result = <span class="hljs-keyword">new</span> Toast(context); LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View v = inflate.inflate(com.android.<span class="hljs-keyword">internal</span>.R.layout.transient_notification, <span class="hljs-keyword">null</span>); TextView tv = (TextView)v.findViewById(com.android.<span class="hljs-keyword">internal</span>.R.id.message); tv.setText(text); result.mNextView = v; result.mDuration = duration; <span class="hljs-keyword">return</span> result; }` transient_notification这个布局文件代码是这样的 `<span class="hljs-tag"><<span class="hljs-title">LinearLayout</span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:orientation</span>=<span class="hljs-value">"vertical"</span> <span class="hljs-attribute">android:background</span>=<span class="hljs-value">"?android:attr/toastFrameBackground"</span>></span> <span class="hljs-tag"><<span class="hljs-title">TextView</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@android:id/message"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:layout_weight</span>=<span class="hljs-value">"1"</span> <span class="hljs-attribute">android:layout_gravity</span>=<span class="hljs-value">"center_horizontal"</span> <span class="hljs-attribute">android:textAppearance</span>=<span class="hljs-value">"@style/TextAppearance.Toast"</span> <span class="hljs-attribute">android:textColor</span>=<span class="hljs-value">"@color/bright_foreground_dark"</span> <span class="hljs-attribute">android:shadowColor</span>=<span class="hljs-value">"#BB000000"</span> <span class="hljs-attribute">android:shadowRadius</span>=<span class="hljs-value">"2.75"</span> /></span> <span class="hljs-tag"></<span class="hljs-title">LinearLayout</span>></span>` 那么我们想要修改Toast的文字消息样式,其实就是修改Toast根布局和message这个TextView。 ...

2016年8月25日 · 4 分钟 · 天边的星星

android webView网页表单自动登录(单点登录)

今天帮助网友解决了一个在应用中登录后进应用的网页自动登录。 在这里分享给大家,希望能帮助更多的人。直接上代码: /** * 网页自动登录 * http://haohailai.taobao.com/ * @author xiehaibo * */ public class MainActivity extends Activity { private WebView webView1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView1 = (WebView) findViewById(R.id.webView1); // 设置支持JavaScript脚本 WebSettings webSettings = webView1.getSettings(); webSettings.setJavaScriptEnabled(true); // 设置可以访问文件 webSettings.setAllowFileAccess(true); // 设置支持缩放 webSettings.setBuiltInZoomControls(true); // 设置WebViewClient webView1.setWebViewClient(new WebViewClient() { public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onPageFinished(WebView view, String url) { Log.d("admin", "网页加载完了"); String uname = "帐号"; String password = "密码"; // 加载完了再调用js登录代码 view.loadUrl("javascript: {" + "document.getElementById('username').value = '" + uname + "';" + "document.getElementById('password').value = '" + password + "';" + "var frms = document.getElementsByName('tableForm');" + "frms[0].submit(); };"); // 登录成功后加载框取消 super.onPageFinished(view, url); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { Log.d("admin", "网页开始加载"); // 在这里可以创建一个加载框。。。 super.onPageStarted(view, url, favicon); } }); webView1.loadUrl("网页地址,包含登录表单"); } } 注意的是: ...

2016年8月22日 · 1 分钟 · 天边的星星

android获取web服务器端session并验证登陆

传统网页实现用户登陆一般采用session或cookie记录用户基本信息又或者两者结合起来使用。android也可以采用session实现用户登陆验证并记录用户登陆状态时的基本信息,session是在服务器端的;而类似cookie的记录方式,则可以在客户端采用xml文件记录用户基本信息,重要数据则可以加密存放客户端。android实现的session登陆功能与网页请求不同的是,网页形式的一次成功的登陆请求后,再点击其他页面时,session一直是存在的,在一定时间内是有效的;而采用android客户端请求的一次成功登陆后,再次发送新的请求,则会产生新的session,而不是原来的。这就需要记录session的id号,并在整个请求过程中都记录并传递这个id号,才能保证session的一致性。 以获取php session为例,主要思路实现分为客户端与服务器端3个步骤。 附件:源码下载 1.)客户端(ANDROID) 建立一个名为GetWebSession的android项目,编写GetWebSession.java,LoginSuccessActivity.java,GetUserInfoActivity.java三个activity类。 GetWebSession.java主要是实现布局界面以及发送用户名和密码到php服务器端验证,如果验证成功则跳转到LoginSuccessActivity.java类。GetWebSession.java主要涉及到与服务器端连接请求,对从服务器端返回的json数据(如用户id,session等)进行解析,并存入HashMap,传递到LoginSuccessActivity.java 代码如下: [view plain](http://www.yoyong.com/archives/178#)[copy to clipboard](http://www.yoyong.com/archives/178#)[print](http://www.yoyong.com/archives/178#)[?](http://www.yoyong.com/archives/178#) - <span class="keyword">package</span> com.login.main; - <span class="keyword">import</span> java.io.IOException; - <span class="keyword">import</span> java.io.UnsupportedEncodingException; - <span class="keyword">import</span> java.util.ArrayList; - <span class="keyword">import</span> java.util.HashMap; - <span class="keyword">import</span> java.util.List; - <span class="keyword">import</span> org.apache.http.HttpEntity; - <span class="keyword">import</span> org.apache.http.HttpResponse; - <span class="keyword">import</span> org.apache.http.client.ClientProtocolException; - <span class="keyword">import</span> org.apache.http.client.entity.UrlEncodedFormEntity; - <span class="keyword">import</span> org.apache.http.client.methods.HttpPost; - <span class="keyword">import</span> org.apache.http.impl.client.DefaultHttpClient; - <span class="keyword">import</span> org.apache.http.message.BasicNameValuePair; - <span class="keyword">import</span> org.apache.http.protocol.HTTP; - <span class="keyword">import</span> org.apache.http.util.EntityUtils; - <span class="keyword">import</span> org.json.JSONException; - <span class="keyword">import</span> org.json.JSONObject; - <span class="keyword">import</span> android.app.Activity; - <span class="keyword">import</span> android.content.Context; - <span class="keyword">import</span> android.content.Intent; - <span class="keyword">import</span> android.os.Bundle; - <span class="keyword">import</span> android.view.View; - <span class="keyword">import</span> android.view.View.OnClickListener; - <span class="keyword">import</span> android.widget.Button; - <span class="keyword">import</span> android.widget.EditText; - <span class="keyword">import</span> android.widget.Toast; - <span class="keyword">public</span> <span class="keyword">class</span> GetWebSession <span class="keyword">extends</span> Activity { - <span class="comment">/** Called when the activity is first created. */</span> - <span class="keyword">private</span> EditText user; - <span class="keyword">private</span> EditText password; - <span class="keyword">private</span> Button loginBtn; - <span class="keyword">private</span> Button logoutBtn; - <span class="comment">//主要是记录用户会话过程中的一些用户的基本信息</span> - <span class="keyword">private</span> HashMap<String, String> session =<span class="keyword">new</span> HashMap<String, String>(); - <span class="annotation">@Override</span> - <span class="keyword">public</span> <span class="keyword">void</span> onCreate(Bundle savedInstanceState) { - <span class="keyword">super</span>.onCreate(savedInstanceState); - setContentView(R.layout.main); - user=(EditText)findViewById(R.id.user); - password=(EditText)findViewById(R.id.password); - loginBtn=(Button)findViewById(R.id.loginBtn); - loginBtn.setOnClickListener(loginClick); - logoutBtn=(Button)findViewById(R.id.logoutBtn); - logoutBtn.setOnClickListener(logoutClick); - } - OnClickListener loginClick=<span class="keyword">new</span> OnClickListener() { - <span class="annotation">@Override</span> - <span class="keyword">public</span> <span class="keyword">void</span> onClick(View v) { - <span class="comment">// TODO Auto-generated method stub</span> - <span class="keyword">if</span>(checkUser()){ - Toast.makeText(v.getContext(), <span class="string">&#8220;用户登录成功!&#8221;</span>, Toast.LENGTH_SHORT).show(); - Context context = v.getContext(); - Intent intent = <span class="keyword">new</span> Intent(context, - LoginSuccessActivity.<span class="keyword">class</span>); - <span class="comment">//传递session参数,在用户登录成功后为session初始化赋值,即传递HashMap的值</span> - Bundle map = <span class="keyword">new</span> Bundle(); - map.putSerializable(<span class="string">&#8220;sessionid&#8221;</span>, session); - intent.putExtra(<span class="string">&#8220;session&#8221;</span>, map); - context.startActivity(intent); <span class="comment">// 跳转到成功页面</span> - } - <span class="keyword">else</span> - Toast.makeText(v.getContext(), <span class="string">&#8220;用户验证失败!&#8221;</span>, Toast.LENGTH_SHORT).show(); - } - }; - OnClickListener logoutClick=<span class="keyword">new</span> OnClickListener() { - <span class="annotation">@Override</span> - <span class="keyword">public</span> <span class="keyword">void</span> onClick(View v) { - <span class="comment">// TODO Auto-generated method stub</span> - System.exit(<span class="number"></span>); - } - }; - <span class="keyword">private</span> <span class="keyword">boolean</span> checkUser(){ - String username=user.getText().toString(); - String pass=password.getText().toString(); - DefaultHttpClient mHttpClient = <span class="keyword">new</span> DefaultHttpClient(); - HttpPost mPost = <span class="keyword">new</span> HttpPost(<span class="string">&#8220;http://10.0.2.2/web/php/login.php&#8221;</span>); - <span class="comment">//传递用户名和密码相当于</span> - <span class="comment">//http://10.0.2.2/web/php/login.php?username=&#8221;&password=&#8221;</span> - List<BasicNameValuePair> pairs = <span class="keyword">new</span> ArrayList<BasicNameValuePair>(); - pairs.add(<span class="keyword">new</span> BasicNameValuePair(<span class="string">&#8220;username&#8221;</span>, username)); - pairs.add(<span class="keyword">new</span> BasicNameValuePair(<span class="string">&#8220;password&#8221;</span>, pass)); - <span class="keyword">try</span> { - mPost.setEntity(<span class="keyword">new</span> UrlEncodedFormEntity(pairs, HTTP.UTF_8)); - } <span class="keyword">catch</span> (UnsupportedEncodingException e) { - <span class="comment">// TODO Auto-generated catch block</span> - e.printStackTrace(); - } - <span class="keyword">try</span> { - HttpResponse response = mHttpClient.execute(mPost); - <span class="keyword">int</span> res = response.getStatusLine().getStatusCode(); - <span class="keyword">if</span> (res == <span class="number">200</span>) { - HttpEntity entity = response.getEntity(); - <span class="keyword">if</span> (entity != <span class="keyword">null</span>) { - String info = EntityUtils.toString(entity); - System.out.println(<span class="string">&#8220;info&#8212;&#8212;&#8212;&#8211;&#8220;</span>+info); - <span class="comment">//以下主要是对服务器端返回的数据进行解析</span> - JSONObject jsonObject=<span class="keyword">null</span>; - <span class="comment">//flag为登录成功与否的标记,从服务器端返回的数据</span> - String flag=<span class="string">&#8220;&#8221;</span>; - String name=<span class="string">&#8220;&#8221;</span>; - String userid=<span class="string">&#8220;&#8221;</span>; - String sessionid=<span class="string">&#8220;&#8221;</span>; - <span class="keyword">try</span> { - jsonObject = <span class="keyword">new</span> JSONObject(info); - flag = jsonObject.getString(<span class="string">&#8220;flag&#8221;</span>); - name = jsonObject.getString(<span class="string">&#8220;name&#8221;</span>); - userid = jsonObject.getString(<span class="string">&#8220;userid&#8221;</span>); - sessionid = jsonObject.getString(<span class="string">&#8220;sessionid&#8221;</span>); - } <span class="keyword">catch</span> (JSONException e) { - <span class="comment">// TODO Auto-generated catch block</span> - e.printStackTrace(); - } - <span class="comment">//根据服务器端返回的标记,判断服务端端验证是否成功</span> - <span class="keyword">if</span>(flag.equals(<span class="string">&#8220;success&#8221;</span>)){ - <span class="comment">//为session传递相应的值,用于在session过程中记录相关用户信息</span> - session.put(<span class="string">&#8220;s_userid&#8221;</span>, userid); - session.put(<span class="string">&#8220;s_username&#8221;</span>, name); - session.put(<span class="string">&#8220;s_sessionid&#8221;</span>, sessionid); - <span class="keyword">return</span> <span class="keyword">true</span>; - } - <span class="keyword">else</span>{ - <span class="keyword">return</span> <span class="keyword">false</span>; - } - } - <span class="keyword">else</span>{ - <span class="keyword">return</span> <span class="keyword">false</span>; - } - } - } <span class="keyword">catch</span> (ClientProtocolException e) { - <span class="comment">// TODO Auto-generated catch block</span> - e.printStackTrace(); - } <span class="keyword">catch</span> (IOException e) { - <span class="comment">// TODO Auto-generated catch block</span> - e.printStackTrace(); - } - <span class="keyword">return</span> <span class="keyword">false</span>; - } - } LoginSuccessActivity.java主要获取php的session唯一的标识id以及用户的一些基本信息,session id则作为本次用户登录状态在服务器的唯一标识,即确定用户的唯一状态进行相关操作。LoginSuccessActivity.java类的方法与GetWebSession.java类似。其主要功能是获取session id后再次发送session id到服务器进行验证,根据封装的session数据验证用户操作权限等。 代码如下: ...

2016年8月22日 · 14 分钟 · 天边的星星

推荐!国外程序员整理的Java资源大全

构建 这里搜集了用来构建应用程序的工具。 Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建。Maven优于Apache Ant。后者采用了一种过程化的方式进行配置,所以维护起来相当困难。 Gradle:Gradle采用增量构建。Gradle通过Groovy编程而不是传统的XML声明进行配置。Gradle可以很好地配合Maven进行依赖管理,并且把Ant脚本当作头等公民。 字节码操作 编程操作Java字节码的函数库。 ASM:通用底层字节码操作及分析。 Javassist:尝试简化字节码编辑。 Byte Buddy:使用“流式API”进一步简化字节码生成。 代码分析 软件度量和质量评估工具。 Checkstyle:对编程规范和标准进行静态分析。 FindBugs:通过字节码静态分析找出潜在Bug。 PMD:对源代码中不良编程习惯进行分析。 SonarQube:通过插件集成其它分析组件,提供评估最终结果报告。 编译器 创建分析器、解释器和编译器的框架。 ANTLR:功能完备的自顶向下分析复杂框架。 JavaCC:相对ANTLR更具体,上手略为简单。支持语法语法超前预测(syntactic lookahead)。 持续集成 支持持续集成、测试和应用发布的工具。 Bamboo:Atlassian的持续集成(CI)解决方案,包含很多其它产品。 CircleCI:提供托管服务,可免费试用。 Codeship:提供托管服务,提供有限免费计划。 Go:ThoughtWork开源持续集成解决方案。 Jenkins:提供基于服务器的部署服务。 TeamCity:JetBrain持续集成方案,提供免费版。 Travis:提供托管服务,常用于开源项目。 数据库 简化数据库交互的工具、库。 Flyway:使用Java API轻松完成数据库迁移。 H2:小型SQL数据库,以内存操作著称。 JDBI:便捷的JDBC抽象。 jOOQ:基于SQL schema生成类型安全代码。 Presto:针对大数据的分布式SQL查询引擎。 Querydsl:针对Java的类型安全统一查询。 日期和时间 处理日期和时间的函数库。 Joda-Time:Java 8出现之前,它是日期、时间处理的标准函数库。 Time4J:Java高级日期、时间函数库。 依赖注入 帮助代码实现控制反转模式的函数库。 Dagger :编译期的注入框架,没有使用反射,主要用于Android开发。 Guice:轻量级注入框架,功能强大可与Dagger媲美。 开发库 从基础层次上改进开发流程。 AspectJ:面向切面编程扩展,与程序无缝连接。 Auto:源代码生成器集合。 DCEVM:通过修改JVM,在运行时可无限次重定义已加载的类。OpenJDK 7、8已提供支持,详情可查看这个分支(fork)。 JRebel:商用软件,无需重新部署可即时重新加载代码及配置。 Lombok:代码生成器,旨在减少Java冗余代码。 RxJava:使用JVM中可观察序列,创建异步、基于事件应用程序的函数库。 Spring Loaded:另一个JVM类重载代理。 vert.x:JVM多语言事件驱动应用框架。 分布式应用 用来开发分布式、具有容错性应用程序的函数库和框架。 Akka:构建并发、分布式和具有容错功能的事件驱动应用程序所需的工具包和运行时。 Apache Storm:分布式实时计算系统。 Apache ZooKeeper:为大型分布式系统,使用分布式配置、同步和命名注册提供协调服务。 Hazelcast:分布式、高可扩展性内存网格。 Hystrix:为分布式系统提供延迟和容错处理。 JGroups:一组提供可靠消息传输的工具包,可用来创建集群。集群中的节点可互相发送消息。 Quasar:为JVM提供轻量级线程和Actor。 发布 使用本机格式分发Java应用程序的工具。 ...

2016年8月18日 · 3 分钟 · 天边的星星

CentOS+Nginx一步一步开始配置负载均衡

Nginx负载均衡的理解 Nginx是一个轻量级的、高性能的WebServer,他主要可以干下面两件事: 作为http服务器(和apache的效果一样) 作为反向代理服务器实现负载均衡 现在Nginx到处都可以见到,经常会看到宕机后的网页会显示nginx的字样,这也说明Nginx由于高性能、使用配置简、开源单这些特点被越来越多的用户所接受,所使用。 其中第一种作为http服务器,结合php-fpm进程,对发来的请求进行处理,nginx本身并不会解析php,他只是作为一个服务器,接受客户端发来的请求,如果是php请求,则交给php进程处理,并将php处理完成之后的结果发送给客户端。这个很简单,安装好nginx+php-fpm之后配置好各自的配置文件,启动就可以实现。运行原理可以看下面这段解释: Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux下是socket(这个socket可以是文件socket,也可以是ip socket)。为了调用CGI程序,还需要一个FastCGI的wrapper(wrapper可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。当Nginx将CGI请求发送给这个socket的时候,通过FastCGI接口,wrapper接收到请求,然后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据通过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据发送给客户端。这就是Nginx+FastCGI的整个运作过程,如图下图所示。 [][1] 上面这段话解释了nginx+fastcgi的运行机制,在nginx配置文件中会对请求进行匹配,并作做出相应的处理,比如说直接返回错误文件(这里和上面说的有点区别,我估计是nginx内部对html等这些静态文件可以做类似上图的解析),使用php进程对php请求进行处理(这里的php进程可以是多个)。 第二种是用反向代理事项负载均衡,这个其实其实很简单,说起来就是自己定义一组server,对请求进行匹配,并将请求转给server中的任意一个处理,来减轻每个server的压力,先看看网上对反向向代理的定义: 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。 反向代理是和正向代理(或者叫代理) 相反的,代理大家定听过吧,为了更方便的访问B资源,通过A资源间接的访问B资源,特点就是用户知道自己最终要访问的网站是什么,但是反向代理用户是不知道代理服务器后边做了什么处理的,反向代理中服务真正的处理服务器放在内网,对外网而言只可以访问反向代理服务器,这也大大提高了安全性。 安装软件 nginx安装很简单 1、安装nginx需要的环境,pcre(作用rewrite)、zlib(作用压缩)、ssl,这个也可以自己下载编译安装 yum -y install zlib; yum –y install pcre; yum –y install openssl; 2、下载安装nginx-*.tar.gz。 tar –zxvf nginx-1.2.8.tar.gz –C ./; cd nginx-1.2.8; ./congigure –prefix=/usr/local/nginx; make && make install; 3、配置 这里配置的时候只需要修改http{}之间的内容就行了,修改的第一个地方就是设置服务器组,在http节点之间添加 upstream myServer{ server www.88181.com:80; #这里是你自己要做负载均衡的服务器地址1 server www.linux.com:8080; #这里是要参与负载均衡的地址2 } nginx中的upstream支持下面几种方式:轮询(默认,按照时间顺序对所有服务器一个一个的访问,如果有服务器宕机,会自动剔除)、weight(服务器的方位几率和weight成正比,这个可以在服务器配置不均的时候进行配置)、ip_hash(对每个请求的ip进行hash计算,并按照一定的规则分配对应的服务器)、fair(按照每台服务器的响应时间(rt)来分配请求,rt晓得优先分配)、url_hash(按照访问url的hash值来分配请求),我这里使用了默认的轮训方式。 将请求指向myServer location / { proxy_pass http://myServer; } 完整的文件(删除注释)如下: worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream myServer{ server www.linux.com:80; server www.88181.com:8080; } server { listen 80; server_name my22; location / { proxy_pass http://myServer; } } } 设置反向代理后端作为负载均衡的两个服务器 ...

2016年8月18日 · 1 分钟 · 天边的星星