Tips and Tricks Posts

August 21, 2012

High Performance Computing – GPU v. CPU

By in SoftLayer, Technology, Tips and Tricks

Sometimes, technical conversations can sound like people are just making up tech-sounding words and acronyms: “If you want HPC to handle Gigaflops of computational operations, you probably need to supplement your server’s CPU and RAM with a GPU or two.” It’s like hearing a shady auto mechanic talk about replacing gaskets on double overhead flange valves or hearing Chris Farley (in Tommy Boy) explain that he was “just checking the specs on the endline for the rotary girder” … You don’t know exactly what they’re talking about, but you’re pretty sure they’re lying.

When we talk about high performance computing (HPC), a natural tendency is to go straight into technical specifications and acronyms, but that makes the learning curve steeper for people who are trying to understand why a solution is better suited for certain types of workloads than technology they are already familiar with. With that in mind, I thought I’d share a quick explanation of graphics processing units (GPUs) in the context of central processing units (CPUs).

The first thing that usually confuses people about GPUs is the name: “Why do I need a graphics processing unit on a server? I don’t need to render the visual textures from Crysis on my database server … A GPU is not going to benefit me.” It’s true that you don’t need cutting-edge graphics on your server, but a GPU’s power isn’t limited to “graphics” operations. The “graphics” part of the name reflects the original intention for kind of processing GPUs perform, but in the last ten years or so, developers and engineers have come to adapt the processing power for more general-purpose computing power.

GPUs were designed in a highly parallel structure that allows large blocks of data to be processed at one time — similar computations are being made on data at the same time (rather than in order). If you assigned the task of rendering a 3D environment to a CPU, it would slow to a crawl — it handles requests more linearly. Because GPUs are better at performing repetitive tasks on large blocks of data than CPUs, you start see the benefit of enlisting a GPU in a server environment.

The Folding@home project and bitcoin mining are two of the most visible distributed computing projects that GPUs are accelerating, and they’re perfect examples of workloads made exponentially faster with the parallel processing power of graphics processing units. You don’t need to be folding protein or completing a blockchain to get the performance benefits, though; if you are taxing your CPUs with repetitive compute tasks, a GPU could make your life a lot easier.

If that still doesn’t make sense, I’ll turn the floor over to the Mythbusters in a presentation for our friends at NVIDIA:

SoftLayer uses NVIDIA Tesla GPUs in our high performance computing servers, so developers can use “Compute Unified Device Architecture” (CUDA) to easily take advantage of their GPU’s capabilities.

Hopefully, this quick rundown is helpful in demystifying the “technobabble” about GPUs and HPC … As a quick test, see if this sentence makes more sense now than it did when you started this blog: “If you want HPC to handle Gigaflops of computational operations, you probably need to supplement your server’s CPU and RAM with a GPU or two.”

-Phil

August 15, 2012

Managing Support Tickets: Email Subscriptions

By in Customer Service, SoftLayer, Tips and Tricks

This week, the development team rolled out some behind-the-scenes support functionality that I think a lot of our customers will want to take advantage of, so I put together this quick blog post to spread the word about it. With the new release, the support department is able to create “Ticket Email Subscriptions” for different ticket groups on every customer account. As a customer, you might not be jumping up and down with joy after reading that one-sentence description, but after you hear a little more about the functionality, if you’re not clapping, I hope you’ll at least give us a thumbs-up.

To understand the utility of the new ticket email subscription functionality, let’s look at how normal tickets work in the SoftLayer portal without email subscriptions:

User Creates Ticket

  1. User A creates a ticket.
  2. User A becomes the owner of that ticket.
  3. When SoftLayer responds to the ticket, an email notification is sent to User A to let him/her know that the ticket has been updated.

SoftLayer Creates Ticket

  1. SoftLayer team creates a ticket on a customer’s account.
  2. The primary customer contact on the account is notified of the new ticket.
  3. Customer logs into the portal and responds to ticket.
  4. Customer gets notifications of updates (as described above).

There’s nothing wrong with the existing support notification process, but that doesn’t mean there aren’t ways to make the process better. What if User A creates an urgent ticket on his/her way out the door to go on vacation? User B and User C aren’t notified when an update is posted on User A’s ticket, so the other users aren’t able to get to the ticket and respond as quickly as they would have if they received the notification. What if the primary customer contact on the account isn’t the best person to receive a monitoring alert? The administrator who will investigate the monitoring alert has to see the new ticket on the account or hear about it from the primary contact (who got the notification).

Ticket email subscriptions allow for customers to set contact addresses to be notified when a ticket is created, edited or moved in a particular ticket group. Here are the ticket groups differentiated in our initial release:

  • Billing – Any ticket in our Billing department
  • Maintenance – Scheduled maintenance notifications for specific servers
  • Network Protection – DDoS mitigation and Null Routes
  • Monitoring – Host Down Alerts
  • CST, SysAdmin and Hardware – Any ticket in our support and data center departments
  • Managed Services – Tickets that relate to any managed services
  • Network Maintenance – Scheduled network maintenance

You’ll notice that Abuse isn’t included in this list, and the only reason it’s omitted is because you’ve always been able to designate a contact on your account for abuse-related tickets … Ticket subscriptions extend that functionality to other ticket groups.

Because only one email address can be “subscribed” to notifications in each ticket group, we recommend that customers use their own distribution lists as the email contacts. With a DL as the contact, you can enable multiple users in your organization to receive notifications, and you can add and remove users from each distribution list on your end quickly and easily.

When User A creates a ticket with the data center and goes on vacation, as soon as SoftLayer responds to the ticket, User A will be notified (as usual), and the supportsubscription@yourdomain.com distribution will get notified as well. When a network maintenance is ticket is created by SoftLayer, the netmaintsubscription@yourdomain.com distribution will be notified.

Ticket email subscriptions are additive to the current update notification structure, and they are optional. If you want to set up ticket email subscriptions on your account, create a ticket for the support department and provide us with the email addresses you’d like to subscribe to each of the ticket groups.

We hope this tool helps provide an even better customer experience for you … If you don’t mind, I’m going to head back to the lab to work with the dev team to cook up more ways to add flexibility and improvements into the customer experience.

-Chris

August 8, 2012

No iFrames! Dynamically Resize Divs with jQuery.

By in Development, Tips and Tricks

It’s no secret that iframes are one of the most hated methods of web page layouts in the web development world — they are horrible for SEO, user experience and (usually) design. I was recently charged with creating a page that needed functionality similar to what iframes would normally provide, and I thought I’d share the non-iframe way I went about completing that project.

Before I get into the nitty-gritty of the project, I should probably unpack a few of the reasons why iframes are shunned. When a search engine indexes a page with iframes, each iframe is accurately recorded as a separate page — iframes embed the content of one we page inside of another, so it makes sense. Because each of those “pages” is represented in a single layout, if a user wanted to bookmark your site, they’d probably have a frustrating experience when they try to return to your site, only to find that they are sent directly to the content in one of the frames instead of seeing the entire layout. Most often, I see when when someone has a navigation bar in one frame and the main content in the other … The user will bookmark the content frame, and when they return to the site, they have no way to navigate the pages. So what’s a developer to do?

The project I was tasked with required the ability to resize only certain sections of a page, while asynchronously shrinking another section so that the entire page would always stay the same size, with only the two sections inside changing size.

Let’s look at an example with two divs, side by side on a web page:

iFrame Tutorial

One div will contain a navigation menu to jump to different pages of the website (#sidebar), and the second div will contain all the content for that page (#content). If some of the elements in #sidebar are too long to read with the default width of the div, we want to let the user freely resize the two divs without changing the width of the page.

Our task is straightforward: When #sidebar expands in width, also expand the navigation and shrink #content along with the main content inside #content. If #sidebar shrinks, the navigation, #content and main content would respond accordingly as well:

iFrame Tutorial

It’s a relatively easy concept to do with iFrames … But then you remember that iframes are no longer cool (yes, there was a time long ago when iframes were cool). I decided to turn to my favorite alternative — jQuery — and the fix was actually a lot easier than I expected, and it worked beautifully. Let’s run through a step-by-step tutorial.

1. HTML

Lay out your two divs:

<div id="sidebar"> 
	<div class="sidebar-menu">
		<!-- all your sidebar/navigational items go here -->
	</div>
</div>
<div id="content">
	<!-- all your main content goes here -->
</div>

2. CSS

Style your divs:

#sidebar {
       width: 49%;
}
#content {
	width: 49%;
        float: left;
}

3. jQuery

Now that we have our two divs side by side, let’s apply some jQuery magic. To do that, Let’s include our jQuery files in the <HEAD> of our document:

<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>

Now that we have the necessary scripts, we can write our function:

<script type="text/javascript">
  $(document).ready(function() {
    $( "#sidebar" ).resizable({      
    });
    $("#sidebar ").bind("resize", function (event, ui) {
            var setWidth = $("#sidebar").width();
            $('#content).width(1224-setWidth);
            $('.menu).width(setWidth-6);
        });
  });
</script>

I know that might seem like an intimidating amount of information, so let’s break it down:

   $( "#sidebar" ).resizable({      
   });

This portion simply makes the div with the ID of “sidebar” resizable (which accomplishes 33% of what we want it to do).

   $("#sidebar ").bind("resize", function (event, ui) {

By using the .bind, we are able to trigger other events when #sidebar is called.

            var setWidth = $("#sidebar").width();
            $('#content).width(1224-setWidth);

This is where the magic happens. We’re grabbing the current width of #sidebar and subtracting it from the width you want your site to be. This code is what keeps your page stays the same width with only the divs changing sizes.

            $('.menu).width(setWidth-6);

This part of the code that expands the contents in the navigation along with #sidebar.

You can see a working example of iframe-like functionality with jQuery here: http://jqueryui.com/demos/resizable/

The only part you won’t find there is the trick to adjust a corresponding div’s size to make it grow/shrink with the first … I had a heck of a time searching that on the web, so hopefully this quick tutorial will help other developers who might be searching for this kind of functionality!

- Cassandra

August 2, 2012

Meet Memcached: A Developer’s Best Friend

By in Development, Tips and Tricks

Whether you’re new to software development or you’ve been a coder since the punchcard days, at some point, you’ve probably come across horrendous performance problems with your website or scripts. From the most advanced users — creating scripts so complex that their databases flooded with complex JOINs — to the novice users — putting SQL calls in loops — database queries can be your worst nightmare as a developer. I hate to admit it, but I’ve experienced some these nightmares first-hand as a result of some less-than-optimal coding practices when writing some of my own scripts. Luckily, I’ve learned how to use memcached to make life a little easier.

What is Memcached?

Memcached is a free and open source distributed memory object caching system that allows the developer to store any sort of data in a temporary cache for later use, so they don’t have to re-query it. By using memcached, a tremendous performance load can be decreased to almost nil. One of the most noteworthy features of the system is that it doesn’t cache EVERYTHING on your site/script; it only caches data that is sure to be queried often. Originally developed in 2003 by Brad Fitzpatrick to improve the site performance of LiveJournal.com, memcached has grown tremendously in popularity, with some of the worlds biggest sites — Wikipedia, Flickr, Twitter, YouTube and Craigslist — taking advantage of the functionality.

How Do I Use Memcache?

After installing the memcached library on your server (available at http://memcached.org/), it’s relatively simple to get started:

<?php
  // Set up connection to Memcached
  $memcache = new Memcached();
  $memcache->connect('host', 11211) or die("Could not connect");
 
  // Connect to database here
 
  // Check the cache for your query
  $key = md5("SELECT * FROM memcached_test WHERE id=1");
  $results = $memcache->get($key);
 
  // if the data exists in the cache, get it!
  if ($results) {
      echo $results['id'];
      echo 'Got it from the cache!';
  } else {
    // data didn't exist in the cache
    $query = "SELECT * FROM memcached_test WHERE id=1");
  $results = mysql_query($query);
  $row = mysql_fetch_array($results);
  print_r($row);
 
  // though we didn't find the data this time, cache it for next time!
  $memcache->set($key, $row, TRUE, 30); 
  // Stores the result of the query for 30 seconds
  echo 'In the cache now!';
 
  }
 
?>

Querying the cache is very similar to querying any table in your database, and if that data isn’t cached, you’ll run a database query to get the information you’re looking for, and you can add that information to the cache for the next query. If another query for the data doesn’t come within 30 seconds (or whatever window you specify), memcached will clear it from the cache, and the data will be pulled from the database.

So come on developers! Support memcached and faster load times! What other tools and tricks do you use to make your applications run more efficiently?

-Cassandra

July 26, 2012

Global IP Addresses – What Are They and How Do They Work?

By in SoftLayer, Technology, Tips and Tricks

SoftLayer recently released “Global IPs” to a good amount of internal fanfare, and I thought I’d share a little about it with the blog audience in case customers have questions about what Global IPs are and how they work. Simply put, Global IP addresses can be provisioned in any data center on the SoftLayer network and moved to another facility if necessary. You can point it to a server in Dallas, and if you need to perform maintenance on the server in Dallas, you can move the IP address to a server in Amsterdam to seamlessly (and almost immediately) transition your traffic. If you spin up and turn down workloads on cloud computing instances, you have the ability to maintain and a specific IP address when you completely turn down an environment, and you can quickly reprovision the IP on a new instance when you spin up the next workload.

How Do Global IPs Work?

The basics of how the Internet works are simple: Packets are sent between you and a server somewhere based on the location of the content you’ve requested. That location is pinpointed by an IP address that is assigned to a specific server or cloud. Often for various reasons, blocks of IP addresses are provisioned in one region or location, so Global IPs are a bit of a departure from the norm.

When you’re sending/receiving packets, you might thing the packets “know” the exact physical destination as soon as they’re directed to an IP address, but in practice, they don’t have to … The packets are forwarded along a path of devices with a general idea of where the exact location will be, but the primary concern of each device is to get the all packets to the next hop in the network path as quickly as possible by using default routes and routing tables. As an example, let’s follow a packet as it comes from an external webserver and detail how it gets back to your machine:

  1. The external webserver sends the packet to a local switch.
  2. The switch passes it to a router.
  3. The packet traverses a number of network hops (other routers) and enters the Softlayer network at one of the backbone routers (BBR).
  4. The BBR looks at the IP destination and compares it to a table shared and updated with the other routers on SoftLayer’s network, and it locates the subnet the IP belongs to.
  5. The BBR determines behind which distribution aggregate router (DAR) the IP is located, then it to the closest BBR to that DAR.
  6. The DAR gets the packet, looks at its own tables, and finds the front-end customer router (FCR) that the subnet lives on, and sends it there.
  7. The FCR routes the packet to the front-end customer switch (FCS) that has that IP mapped to the proper MAC address.
  8. The switch then delivers the packet through the proper switchport.
  9. Your server gets the packet from the FCS, and the kernel goes, “Oh yes, that IP on the public port, I’ll accept this now.”

All of those steps happen in an instant, and for you to be reading this blog, the packets carrying this content would have followed a similar pattern to the browser on your computer.

The process is slightly different when it comes to Global IP addresses. When a packet is destined for a Global IP, as soon as it gets onto the SoftLayer network (step 4 above), the routing process changes.

We allocate subnets of IP addresses specifically to the Global IP address pool, and we tell all the BBRs that these IPs are special. When you order a global IP, we peel off one of those IPs and add a static route to your chosen server’s IP address, and then tell all the BBRs that route. Rather than the server’s IP being an endpoint, the network is expecting your server to act as a router, and do something with the packet when it is received. I know that could sound a little confusing since we aren’t really using the server as a router, so let’s follow a packet to your Global IP (following the first three steps from above):

  1. The BBR notes that this IP belongs to one of the special Global IP address subnets, and matches the destination IP with the static route to the destination server you chose when you provisioned the Global IP.
  2. The BBR forwards the packet to the DAR, which then finds the FCR, then hands it off to the switch.
  3. The switch hands the packet to your server, and your server accepts it on the public interface like a regular secondary IP.
  4. Your server then essentially “routes” the packet to an IP address on itself.

Because the Global IP address can be moved to different servers in different locations, whenever you change the destination IP, the static route is updated in our routing table quickly. Because the change is happening exclusively on SoftLayer’s infrastructure, you don’t have to wait on other providers propagate the change. Think of updating your site’s domain to a new IP address via DNS as an example: Even after you update your authoritative DNS servers, you have to wait for your users’ DNS servers to recognize and update the new IP address. With Global IPs, the IP address would remain the same, and all users will follow the new path as soon as the routers update.

This initial release of Global IP addresses is just the tip of the iceberg when it comes to functionality. The product management and network engineering teams are getting customer feedback and creating roadmaps for the future of the product, so we’d love to hear your feedback and questions. If you want a little more in-depth information about installation and provisioning, check out the Global IP Addresses page on KnowledgeLayer.

-Jason

July 25, 2012

ServerDensity: Tech Partner Spotlight

By in Partner Marketplace, Tips and Tricks

We invite each of our featured SoftLayer Tech Marketplace Partners to contribute a guest post to the SoftLayer Blog, and this week, we’re happy to welcome David Mytton, Founder of ServerDensity. Server Density is a hosted server and website monitoring service that alerts you when your website is slow, down or back up.

5 Ways to Minimize Downtime During Summer Vacation

It’s a fact of life that everything runs smoothly until you’re out of contact, away from the Internet or on holiday. However, you can’t be available 24/7 on the chance that something breaks; instead, there are several things you can do to ensure that when things go wrong, the problem can be managed and resolved quickly. To help you set up your own “get back up” plan, we’ve come up with a checklist of the top five things you can do to prepare for an ill-timed issue.

1. Monitoring

How will you know when things break? Using a tool like Server Density — which combines availability monitoring from locations around the world with internal server metrics like disk usage, Apache and MySQL — means that you can be alerted if your site goes down, and have the data to find out why.

Surprisingly, the most common problems we see are some that are the easiest to fix. One problem that happens all too often is when a customer simply runs out of disk space in a volume! If you’ve ever had it happen to you, you know that running out of space will break things in strange ways — whether it prevents the database from accepting writes or fails to store web sessions on disk. By doing something as simple as setting an alert to monitor used disk space for all important volumes (not just root) at around 75%, you’ll have proactive visibility into your server to avoid hitting volume capacity.

Additionally, you should define triggers for unusual values that will set off a red flag for you. For example, if your Apache requests per second suddenly drop significantly, that change could indicate a problem somewhere else in your infrastructure, and if you’re not monitoring those indirect triggers, you may not learn about those other problems as quickly as you’d like. Find measurable direct and indirect relationships that can give you this kind of early warning, and find a way to measure them and alert yourself when something changes.

2. Dealing with Alerts

It’s no good having alerts sent to someone who isn’t responding (or who can’t at a given time). Using a service like Pagerduty allows you to define on-call rotations for different types of alerts. Nobody wants to be on-call every hour of every day, so differentiating and channeling alerts in an automated way could save you a lot of hassle. Another huge benefit of a platform like Pagerduty is that it also handles escalations: If the first contact in the path doesn’t wake up or is out of service, someone else gets notified quickly.

Click to read ServerDensity’s last three tips. »

June 27, 2012

Cloudability: Tech Partner Spotlight

By in Partner Marketplace, Technology, Tips and Tricks

This guest blog comes to us from Cloudability, a featured member of the SoftLayer Technology Partners Marketplace. Cloudability is a cloud budget management service that helps companies manage their cloud spending, prevent overages, reduce waste and save money. In this video we talk to Cloudability Founder and CEO Mat Ellis about how the company developed, and we hear examples of how Cloudability is supporting and businesses money.

5 Things You Need to Know to Control Variable Infrastructure Costs

If you have on premise equipment, then your costs are fixed — you paid your money and now you own a fixed amount of hardware and software. The cloud, on the other hand, has variable costs due to two important features — you only pay for the services you use and it’s scalable, providing the resources you need at any given time. By using a cloud infrastructure, you end up with what we call Variable Infrastructure Costs (VICs).

Most of SoftLayer’s services meet the criteria for a VIC. You need an extra cloud server for a few hours? No problem. More disk? Done.

With great power, comes great responsibility, and the biggest problem with VICs is that they are just like a faucet: Leave it running, and the water bill can add up fast … Not to mention all that waste! Unless you keep a close eye on VICs, you could find yourself in front of your CFO, pleading for your budget’s life.

Cloudability was created to keep those costs under control, and in the course of working with our customers, we’ve come up with a simple five-point checklist of best practices:

1. Collation

Make sure you have insight to all your costs, create a single contract database, and review it regularly. Don’t forget to include total cloud spending alongside your fixed contracts. Talk to your finance department, then drill your employees and tech teams to make sure you REALLY know the whole truth. There can be — and usually is — a disconnect in the organization about how much cloud is really being used.

2. Analysis

Get into the weeds to see why each project is spending what they are spending. Try to calculate some tangible metrics like cost per thousand web pages served or cost per new customer, and benchmark these against public data and common sense.

3. Organization and Rebalancing

Put each of your projects into one of four quadrants:

  1. High Spend/Low Efficiency
  2. High Spend/High Efficiency
  3. Low Spend/Low Efficiency
  4. Low Spend/High Efficiency.

Read the rest of Cloudability’s blog about best practices in variable cost management. »

June 25, 2012

Tips from the Abuse Department: Part 2 – Responding to Abuse Reports

By in Customer Service, SoftLayer, Tips and Tricks

If you’re a SoftLayer customer, you don’t want to hear from the Abuse department. We know that. The unfortunate reality when it comes to hosting a server is that compromises can happen, mistakes can be made, and even the most scrupulous reseller can fall victim to a fraudulent sign-up or sly spammer. If someone reports abusive behavior originating from one of your servers on our network, it’s important to be able to communicate effectively with the Abuse department and build a healthy working relationship.

Beyond our responsibility to enforce the law and our Acceptable Use Policy, the Abuse department is designed to be a valuable asset for our customers. We’ll notify you of all valid complaints (and possibly highlight security vulnerabilities in the process), we’ll assist you with blacklist removal, we can serve as a liaison between you and other providers if there are any problems, and if you operate an email-heavy platform or service, we can help you understand the steps you need to take to avoid activity that may be considered abuse.

At the end of the day, if the Abuse department can maintain a good rapport with our customers, both our jobs can be easier, so I thought this installment in the “Tips from the Abuse Department” series could focus on some best practices for corresponding with Abuse from a customer perspective.

Check Your Tickets

This is the easiest, most obvious recommendation I can give. You’d be surprised at how many service interruptions could be avoided if our customers were more proactive about keeping up with their open tickets. Our portal is a vital tool for your business, so make sure you are familiar with how to access and use it.

Keep Your Contact Information Current

Our ticket system will send notifications to the email address you have on file, so making sure this information is correct and current is absolutely crucial, especially if you aren’t in the habit of checking the ticket system on a regular basis. You can even set a specific address for abuse notifications to be sent to, so make use of this option. The quicker you can respond to an abuse report, the quicker the complaint can be resolved, and by getting the complaint resolved quickly, you avoid any potential service interruption.

If we are unable to reach you by ticket, we may need to call you, so keep your current phone numbers on file as well.

Provide Frequent Updates

Stay in constant communication in the midst of responding to an abuse report, and adhere to the allotted timeline in the ticket. If we don’t see updates that the abusive behavior is being addressed in the grace period we are able to offer, your server is at risk of disconnection. By keeping us posted about the action you’re taking and the time you need to resolve the matter, we’re able to be more flexible.

If a customer on your servers created a spamming script or a phishing account, taking immediate steps to mitigate the issue by suspending that customer is another great way to respond to the process while you’re performing an investigation of how that activity was started. We’ll still want a detailed resolution, but if the abuse is not actively ongoing we can work with you on deadlines.

Be Concise … But Not Too Concise

One-word responses: bad. Page long responses: also not ideal. If given the option we would opt for the latter, but your goal should be to outline the cause and resolution of any reported abusive activity as clearly and succinctly as possible in order to ease communication and expedite closing of the ticket.

Responding to a ticket with, “Fixed,” is not sufficient to for the Abuse department to consider the matter resolved, but we also don’t need a dump of your entire log file. Before the Abuse team can close a ticket, we have to see details of how the complaint was resolved, so if you don’t provide those details in your first response, you can bet we’ll keep following up with you to get them. What details do we need?

Take a Comprehensive Approach

In addition to stopping the abusive activity we want to know:

  1. How/why the issue occurred
  2. What steps are being taken to prevent further issues of that nature

We understand that dealing with abuse issues can often feel like a game of Whack-A-Mole, but if you can show that you’re digging a bit deeper and taking steps to avoid recurrence, that additional work is very much appreciated. Having the Abuse department consider you a proactive, ethical and responsible customer is a worthy goal.

Be Courteous

I’m ending on a similar note to my last blog post because it’s just that important! We understand getting an abuse ticket is a hassle, but please remember that we’re doing our best to protect our network, the Internet community and you.

Unplugging your server is a last resort for us, and we want to make sure everyone is on the same page to prevent us from getting to that last resort. In the unfortunate event that you do experience an abuse issue, please refer back to this blog — it just might save you some headaches and perhaps some unnecessary downtime.

-Jennifer

June 18, 2012

Tips from the Abuse Department: Part 1 – Reporting Abuse

By in Customer Service, SoftLayer, Tips and Tricks

SoftLayer has a dedicated team working around the clock to address complaints of abuse on our network. We receive these complaints via feedback loops from other providers, spam blacklisting services such as Spamcop and Spamhaus, various industry contacts and mailing lists. Some of the most valuable complaints we receive are from our users, though. We appreciate people taking the time to let us know about problems on our network, and we find these complaints particularly valuable as they are non-automated and direct from the source.

It stands to reason that the more efficient people are at reporting abuse, the more efficient we can be at shutting down the activity, so I’ve compiled some tips and resources to make this process easier. Enjoy!

Review our Legal Page

Not only does this page contain our contact details, there’s a wealth of information on our policies including what we consider abuse and how we handle reported issues. For starters, you may want to review our AUP (Acceptable Use Policy) to get a feel for our stance on abuse and how we mitigate it.

Follow Proper Guidelines

In addition to our own policies, there are legal aspects we must consider. For example, a claim of copyright infringement must be submitted in the form of a properly formatted DMCA, pursuant to the Digital Millennium Copyright Act. Our legal page contains crucial information on what is required to make a copyright claim, as well as information on how to submit a subpoena or court order. We take abuse very seriously, but we must adhere to the law as well as our privacy policy in order to protect our customers’ businesses and our company from liability.

Include Evidence

Evidence can take the form of any number of things. A few common examples:

  • A copy of the alleged spam message with full headers intact.
  • A snippet from your log file showing malicious activity.
  • The full URL of a phishing page.

Without evidence that clearly ties abusive activity to a server on our network, we are unable to relay a complaint to our customer. Keep in mind that the complaint must be in a format that allows us to verify it and pass it along, which typically means an email or hard copy. While our website does have contact numbers and addresses, email is your best bet for most types of complaints.

Use Keywords

We use a mail client specifically developed for abuse desks, and it is configured with a host of rules used for filtering and prioritization. Descriptive subject lines with keywords indicating the issue type are very useful. Including the words “Spam,” “Phishing” or “Copyright” in your subject line helps make sure your email is sent to the correct queue and, if applicable, receives expedited processing. Including the domain name and IP address in the body of the email is also helpful.

Follow Up

We work hard to investigate and resolve all complaints received however, due to volume, we typically do not respond to complaining parties. That said, we often rely on user complaints to determine if an issue has resumed or is ongoing so feel free to send a new complaint if activity persists.

Be Respectful

The only portion of your complaint we are likely to relay to our customer is the evidence itself along with any useful notes, which means that paragraph of profanity is read only by hardworking SoftLayer employees. We understand the frustration of being on the receiving end of spam or a DDOS, but please be professional and try to understand our position. We are on your side!

Hopefully you’ve found some of this information useful. When in doubt, submit your complaint to abuse@softlayer.com and we can offer further guidance. Stay tuned for Part 2, where I’ll offer suggestions for SoftLayer customers about how to facilitate better communication with our Abuse department to avoid service interruption if an abuse complaint is filed against you.

-Jennifer

May 23, 2012

Web Development – JavaScript – Creating a Sticky Menu

By in Development, SoftLayer, Technology, Tips and Tricks

When designing websites, I like to focus on ease of use and accessibility for the end user. While creating your site to be friendly to screen readers and text-based browsers is a must, the accessibility I’m referring to is making it easy for your audience to navigate your site and perform certain common actions. By providing an easy interface for your users, you are immediately increasing your chances that they’ll return for more of your site’s goodness.

Thus far in our “Web Development” blog series, we’ve looked at JavaScript Optimization, HTML5 Custom Data Attributes, HTML5 Web Fonts and using CSS to style the Highlight Selection. In this post, we’re going to create a “sticky” menu at the top of a page. As a user scrolls down, the menu will “stick” to the top and always be visible (think of Facebook’s Timeline view), allowing the user quicker access to clicking common links. With some simple HTML, CSS and JavaScript, you can have a sticky menu in no time.

Let’s start with our HTML. We’re going to have a simple header, menu and content section that we’ll throw in our <body> tag.

<header>
    <h1>My Header</h1>
</header>
<nav id="menu">
    <ul id="menu-list">
        <li>Items</li>
    </ul>
</nav>
<div id="content">
    Some content
</div>

For brevity, I’ve shortened the content I show here, but the working example will have all the information. Now we can throw in some CSS to style our elements. The important part here is how the <nav> is styled.

nav#menu {
    background: #FFF;
    clear: both;
    margin: 40px 0 80px 0;
    width: 99.8%;
    z-index: 2;
}
ul#menu-list li {
    border: solid 1px blue;
    list-style-type: none;
    display: inline-block;
    margin: 0 -3px;
    padding: 4px 10px;
    width: auto;
}

We have set the menu’s background to white (#FFF) and given it a z-index of 2 so that when the user scrolls, the menu will stay on top and not be see-through. We’ve also set the list items to be styled inline-block, but you can style your items however you desire.

Now we get to the fun part – the JavaScript. I’ve created a class using Mootools, but similar functionality could be achieved using your favorite JavaScript framework. Let’s examine our initialize method (our constructor) in our Stickit class.

var Stickit = this.Stickit = new Class({
    initialize: function(item, options) {
        // 'item' is our nav#menu in this case
        this.item = document.id(item);
 
        // The element we're scrolling will be the window
        this.scrollTarget = document.id(options.scrollTarget || document.window);
 
        // The 'anchor' is an empty element that will always keep the same location
        // when the user scrolls. This is needed because this.item will change and
        // we cannot rely on it for accurate calculations.
        this.anchor = new Element('div').inject(this.item, 'top');
 
        // The 'filler' is an empty element that we'll use as a space filler for when
        // the 'item' is being manipulated - this will prevent the content below from
        // jumping around when we scroll.
        this.filler = new Element('div').inject(this.item, 'after');
 
        // Set the styles of our 'filler' to match the styles of the 'item'
        this.setFillerStyles();
 
        // Initialize our scroll events – see the next code section for details
        this.initEvents();
    }
});

What we’re doing here is grabbing our element to stick to the top – in this case, nav#menu – and initializing our other important elements. I’ll review these in the next code section.

var Stickit = this.Stickit = new Class({
    ...
    initEvents: function() {
        var that = this,
            // Grab the position of the anchor to be used for comparison during vertical scroll
            anchorOffsetY = this.anchor.getPosition().y,
            // Grab our original styles of our 'item' so that we can reset them later
            originalStyles = this.item.getStyles('margin-top', 'position', 'top');
 
        // This is the function we'll provide as our scroll event handler
        var stickit = function(e) {
            // Determine if we have scrolled beyond our threshold - in this case, our
            // anchor which is located as the first element of our 'item'
            var targetScrollY = that.scrollTarget.getScroll().y,
                fixit = targetScrollY > anchorOffsetY;
 
            if (fixit && that.cache != 'fixed') {
                // If we have scrolled beyond the threshold, fix the 'item' to the top
                // of the window with the following styles: margin-top, position and top
                that.item.setStyles({
                    'margin-top': 0,
                    position: 'fixed',
                    top: 0
                });
                // Show our (empty) filler so that the content below the 'item' does not
                // jump - this would otherwise be distracting to the user
                that.filler.setStyle('display', 'block');
                // Cache our value so that we only set the styles when we need to
                that.cache = 'fixed';
            }
            else if (!fixit && that.cache != 'default') {
                // We have not scrolled beyond the threshold.
                // Hide our filler
                that.filler.setStyle('display', 'none');
                // Reset the styles to our 'item'
                that.item.setStyles(originalStyles);
                // Cache our values so we don't keep resetting the styles
                that.cache = 'default';
            }
        };
 
        // Add our scroll event to the target - the 'window' in this case
        this.scrollTarget.addEvent('scroll', stickit);
        // Fire our scroll event so that all the elements and styles are initialized
        this.scrollTarget.fireEvent('scroll');
    }
});

This method contains the meat of our functionality. The logic includes that we test how far the user has scrolled down on the page. If s/he scrolls past the threshold – in this case, the anchor which is located at the very top of the “stuck” item – then we set the menu to be fixed to the top of the page by setting the CSS values for margin-top, position and top. We also display a filler so that the content below the menu doesn’t jump when we set the menu’s position to fixed. When the user scrolls back to the top, the styles are reset to their original values and the filler is hidden.

To see a full working example, check out this fiddle. The Stickit class I created is flexible enough so that you can “stick” any element to the top of the page, and you can specify a different scrollTarget, which will allow you to scroll another element (besides the window) and allow the item to stick to the top of that element instead of the window. If you want to give that a try, you can specify different options in Stickit and modify your CSS as needed to get it working as you’d like.

Happy coding,

-Philip