1. 程式人生 > >zookeeper+dubbo+nginx叢集和負載均衡簡單例子

zookeeper+dubbo+nginx叢集和負載均衡簡單例子

1:服務層面用Dubbo+Zookeeper實現分散式服務,然後Http web層用 Nginx 實現高可用叢集方案,本文記錄下demo例子

2:windows環境,  zk 3臺偽叢集 ,idea,maven

3:zk叢集已搭建好,首先開起zk叢集  cd /bin 目錄下 zkcli.cmd -server 127.0.0.1:2181 開啟zk客戶端 ls / 能正常連線到server 表示叢集開啟成功

4:idea新建maven project  dubbo-server

5:dubbo-server下新建2個module模組 server-api,server-provider

   server-api 介面類 

    

package com.cn.dubbo;

public interface IGpHello {

String sayHello(String msg);

}

 

   server-provider 介面實現類

   server-provider下的pom.xml引入dubbo,zookeeper相關jar

  

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-server</artifactId>
<groupId>com.cn.dubbo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>server-provider</artifactId>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.cn.dubbo</groupId>
<artifactId>server-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.38</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
</dependency>
</dependencies>
</project>

api中的實現類1
package com.cn.dubbo;

import com.alibaba.dubbo.rpc.RpcContext;

public class GpHelloImpl implements IGpHello {

public String sayHello(String msg) {
return "Hello " + msg + ", response form provider: " + RpcContext.getContext().getLocalAddress();
}
}
api中的實現類2 
package com.cn.dubbo;

import com.alibaba.dubbo.rpc.RpcContext;

public class GpHelloImpl2 implements IGpHello {

public String sayHello(String msg) {
return "Hello " + msg + ", response form provider: " + RpcContext.getContext().getLocalAddress();
}
}
resources目錄下配置2dubbo xml檔案分別對應上面2個實現類
dubbo-client1.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!--提供方資訊-->
<dubbo:application name="dubbo-server" owner="yulong" />
<!--註冊中心-->
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183"/>
<!--多協議配置-->
<dubbo:protocol name="dubbo" port="28081"/>
<dubbo:service interface="com.cn.dubbo.IGpHello" ref="helloService"
protocol="dubbo" />
<bean id="helloService" class="com.cn.dubbo.GpHelloImpl" />
dubbo-client2.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!--提供方資訊-->
<dubbo:application name="dubbo-server" owner="yulong" />
<!--註冊中心-->
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183"/>
<!--多協議配置-->
<dubbo:protocol name="dubbo" port="28082"/>
<dubbo:service interface="com.cn.dubbo.IGpHello" ref="helloService"
protocol="dubbo" />
<bean id="helloService" class="com.cn.dubbo.GpHelloImpl2" />
</beans></beans>
新建2個main方法移動對應的服務
BootstrapCluster1
package com.cn.dubbo;

import com.alibaba.dubbo.container.Main;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class BootstrapCluster1 {

public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context=
new ClassPathXmlApplicationContext("META-INF/spring/dubbo-cluster1.xml");
context.start();
//dubbo自帶了springcontainer log4jcontainer等容器 可以直接main方式啟動容器
//Main.main(new String[]{"spring"});
System.out.println("服務啟動成功");
System.in.read();//阻塞程序
}
}
BootstrapCluster2
package com.cn.dubbo;

import com.alibaba.dubbo.container.Main;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class BootstrapCluster2 {

public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context=
new ClassPathXmlApplicationContext("META-INF/spring/dubbo-cluster2.xml");
context.start();
//dubbo自帶了springcontainer log4jcontainer等容器 可以直接main方式啟動容器
//Main.main(new String[]{"spring"});
System.out.println("服務啟動成功");
System.in.read();//阻塞程序
}
}
同時啟動可以通過配置dubbo-admin管理頁面檢視服務是否啟動,我這直接 ls /dubbo/com.cn.dubbo.IGpHello/providers下已經成功註冊了2個服務

[dubbo%3A%2F%2F172.20.10.6%3A28081%2Fcom.cn.dubbo.IGpHello%3Fanyhost%3Dtrue%26ap
plication%3Ddubbo-server%26dubbo%3D2.5.3%26interface%3Dcom.cn.dubbo.IGpHello%26m
ethods%3DsayHello%26owner%3Dyulong%26pid%3D4864%26side%3Dprovider%26timestamp%3D
1543887881068, dubbo%3A%2F%2F172.20.10.6%3A28082%2Fcom.cn.dubbo.IGpHello%3Fanyho
st%3Dtrue%26application%3Ddubbo-server%26dubbo%3D2.5.3%26interface%3Dcom.cn.dubb
o.IGpHello%26methods%3DsayHello%26owner%3Dyulong%26pid%3D5572%26side%3Dprovider%
26timestamp%3D1543887965460]

6:搭建2個簡單的springmvc web

    springmvc工程

    6.1 :配置pom.xml 引入spring dubbo zk相關jar依賴

   <?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.cn.mvc</groupId>
<artifactId>springmvc</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<name>springmvc Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<!--spring版本-->
<spring.version>4.0.5.RELEASE</spring.version>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.cn.dubbo</groupId>
<artifactId>server-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.38</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
</dependency>

</dependencies>

<build>
<finalName>springmvc</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

  6.2:web.xml中配置

 <!DOCTYPE web-app PUBLIC

 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--Spring MVC 配置 並新增監聽-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dubbo-client.xml</param-value>
</context-param>

<!-- 字元過濾器 傳值亂碼-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!--配置前端控制器 進行請求分發 DispatcherServlet本質也是一個Servlet -->
<servlet>
<!--名字可以自定義-->
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc-dispatcher.xml</param-value>
</init-param>
<!--標記容器啟動的時候就啟動這個servlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!--攔截所有-->
<url-pattern>/</url-pattern>
</servlet-mapping>

</web-app>

index.jsp
<html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<body>
<a href="/developer/hello">dubbo 測試1</a>
</body>
</html>
6.3:resources目錄下配置mvc-dispathcer.xml和dubbo-client.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置包掃描器 -->
<context:component-scan base-package="com.cn.mvc.controller"/>
<!-- 配置註解驅動 -->
<mvc:annotation-driven/>
<!-- 檢視解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--字首-->
<property name="prefix" value="/WEB-INF/views/"/>
<!--字尾-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--提供方資訊-->
<dubbo:application name="dubbo-client" owner="yulong" />
<!--註冊中心-->
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183"/>
<dubbo:reference id="helloService" interface="com.cn.dubbo.IGpHello" protocol="dubbo" />
</beans>
6.4:新建MyController類
package com.cn.mvc.controller;

import com.cn.dubbo.IGpHello;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Scope("prototype")
@Controller
@RequestMapping("/developer")
public class MyController {

@Autowired
private IGpHello helloService;

@ResponseBody
@RequestMapping(value = "/hello", produces = "application/json; charset=utf-8")
public String hello() throws Exception {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String str = helloService.sayHello("我是消費者1號!"+ sf.format(new Date()));
//String string = new String(str.getBytes("ISO-8859-1"), "utf-8");
System.out.println(str);
return str;
}
}
7:新建工程springmvc2
springmvc2和1差不多
index.jsp 和mycontroler類有點差別,其他配置一樣
<html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<body>
<a href="/developer/hello">dubbo 測試2</a>
</body>
</html>

package com.cn.mvc.controller;

import com.cn.dubbo.IGpHello;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Scope("prototype")
@Controller
@RequestMapping("/developer")
public class MyController {

@Autowired
private IGpHello helloService;

@ResponseBody
@RequestMapping(value = "/hello", produces = "application/json; charset=utf-8")
public String hello() throws UnsupportedEncodingException {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String str = helloService.sayHello("我是消費者2號!"+sf.format(new Date()));
//String string = new String(str.getBytes("ISO-8859-1"), "utf-8");
System.out.println(str);
return str;
}
}
分別啟動2個工程注意tomca埠不能佔用 我用的是8081 8082
點選測試1發現能正常返回

Hello 我是消費者1號!2018-12-04 10:00:50, response form provider: 172.20.10.6:28081
點選測試2發現能正常返回 
Hello 我是消費者2號!2018-12-04 10:02:10, response form provider: 172.20.10.6:28082

cmd 客戶端下發現有2個消費者

[zk: 127.0.0.1:2181(CONNECTED) 9] ls /dubbo/com.cn.dubbo.IGpHello/consumers
[consumer%3A%2F%2F172.20.10.6%2Fcom.cn.dubbo.IGpHello%3Fapplication%3Ddubbo-clie
nt%26category%3Dconsumers%26check%3Dfalse%26dubbo%3D2.5.6%26interface%3Dcom.cn.d
ubbo.IGpHello%26methods%3DsayHello%26owner%3Dyulong%26pid%3D644%26protocol%3Ddub
bo%26revision%3D1.0-SNAPSHOT%26side%3Dconsumer%26timestamp%3D1543888927684, cons
umer%3A%2F%2F172.20.10.6%2Fcom.cn.dubbo.IGpHello%3Fapplication%3Ddubbo-client%26
category%3Dconsumers%26check%3Dfalse%26dubbo%3D2.5.6%26interface%3Dcom.cn.dubbo.
IGpHello%26methods%3DsayHello%26owner%3Dyulong%26pid%3D4652%26protocol%3Ddubbo%2
6revision%3D1.0-SNAPSHOT%26side%3Dconsumer%26timestamp%3D1543888846966]
[zk: 127.0.0.1:2181(CONNECTED) 10]

8:dubbo預設是隨機策略訪問zk服務節點,最後把Nginx也配置上去下載後直接解壓 進入到配置檔案中心 修改Nginx.conf  

# 配置負載均衡
upstream dubbo-test-server {
# 伺服器地址
server 127.0.0.1:8081 weight=10;
server 127.0.0.1:8082 weight=10;
}

server {
listen 80;
server_name localhost;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
#root html;
#index index.html index.htm;
proxy_pass http://dubbo-test-server;
}

修改後儲存啟動Nginx

瀏覽器輸入 http://localhost/developer/hello 發現能正常訪問服務

以上是簡單的demo,記錄下自己的實踐