新网的DNS跳转功能很差几乎每周都会停一段时间,公司决定自己做DNS二级域名跳转,开始他们想用apache的rewrite功能来实现。可是二级域名跟要跳转过去的地址几乎没有相关性,我想起以前做的通过域名实现子目录跳转的功能,但是需要使用动态配置,不重起服务器实时生效,于是修改成下面的代码,使用listener每一分钟读取数据库里面的数据到HashMap里面。
[@more@]维护DNS转发HashMap的Servlet
InitDnsServlet.java
public class InitDnsServlet extends HttpServlet implements Serializable
{
private static Logger log = Logger.getLogger(InitDnsServlet.class);
protected static HashMap dnsMap = null;
public void init()
{
try
{
InitDnsMap();
} catch (Exception e)
{
e.printStackTrace(System.out);
}
}
synchronized private static void InitDnsMap()
{
HashMap tmpDnsMap = null;
tmpDnsMap=new HashMap();
Vector vResult = null;
Hashtable table = null;
Connection con = null;
PreparedStatement past = null;
ResultSet rs = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("Oracle jdbc:oracle:thin:@192.168.0.18:1521:orcl","user","pwd");
past = con.prepareStatement("select * from tbl_dns_redirectinfo where drin_state=1");
rs = past.executeQuery();
if(rs!=null) {
while(rs.next()) {
tmpDnsMap.put(rs.getString(1),rs.getString(2));
log.info(rs.getString(1) +" 转向 "+ rs.getString(2));
}
}
}
catch(Exception ex) {
ex.printStackTrace();
}
finally {
try {
rs.close();
past.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
dnsMap=tmpDnsMap;
}
synchronized public static void reloadDnsMap() {
InitDnsMap();
}
synchronized public static HashMap getDnsMap() {
if(dnsMap == null)
{
try {
InitDnsMap();
} catch (Exception e) {
e.printStackTrace();
}
}
return dnsMap;
}
protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException
{}
protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1)throws ServletException, IOException
{}
}
监听程序DNSListener.java 每1分钟刷新一下HashMap
import java.util.Timer;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent;
public class DNSListener implements ServletContextListener {
private java.util.Timer timer = new Timer(true);
public void contextInitialized(ServletContextEvent sce) {
try {
//log.info(dt.formateDate(d) + "*****");
//timer.schedule(new BalanceTimer(), new Date(), 24 * 3600 * 1000);
//服务启动时间的第二天凌晨00:00:01秒执行
java.util.Timer timer= new Timer(true);
timer.schedule(new DnsTimer(), 0, 60*1000);//每1分钟模拟请求一次
} catch (Exception e) {
e.printStackTrace();
}
}
public void contextDestroyed(ServletContextEvent sce) {
timer.cancel();
}
}
TimerTask.java
import java.util.TimerTask;
import com.netqin.dba.dbtools.InitDnsServlet;
public class DnsTimer extends TimerTask {
public void run() {
InitDnsServlet.reloadDnsMap();
}
}
jsp 或servlet 实现跳转:
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.util.HashMap,java.sql.*,com.hem.dba.dbtools.InitDnsServlet" %>
<%
try
{
String dns=request.getRequestURL().toString();
out.println(dns);
dns=dns.toLowerCase();
int i=dns.indexOf(":",7);
if(i<0){i=120;}
int j=dns.indexOf("/",7);
if(i<j) j=i;
HashMap dnsMap=InitDnsServlet.getDnsMap();
if(dnsMap.get(dns.substring(7,j))!=null){
response.sendRedirect("http://"+(String)dnsMap.get(dns.substring(7,j)));
}else{
out.println("不能解析的域名");
}
}
catch (Exception ex)
{
%><%= ex.toString() %><%
}
%>
数据库:
tbl_dns_redirectinfo
drin_dns drin_newurl state
adm.hem.cn heming96.itpub.net/admin.php?re=no 1
这样只要 adm.hem.cn 的ip地址指向我的服务,服务器就会自动跳转了,不过这要求adm.hem.cn 后面不能有别的比如端口、其他uri ,如果要的话需要特殊处理 比如把 uri获取出来之response.sendRedirect("http://"+(String)dnsMap.get(dns.substring(7,j)))+":"+Port+"/"+uri);
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9614263/viewspace-1007868/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/9614263/viewspace-1007868/